diff options
41 files changed, 1112 insertions, 655 deletions
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp index 9bfd710309..4811927106 100644 --- a/cmds/dumpsys/dumpsys.cpp +++ b/cmds/dumpsys/dumpsys.cpp @@ -389,7 +389,7 @@ status_t Dumpsys::writeDump(int fd, const String16& serviceName, std::chrono::mi auto time_left_ms = [end]() { auto now = std::chrono::steady_clock::now(); auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now); - return std::max(diff.count(), 0ll); + return std::max(diff.count(), 0LL); }; int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms())); diff --git a/headers/media_plugin/media/openmax/OMX_AsString.h b/headers/media_plugin/media/openmax/OMX_AsString.h index 8e75b54520..152015b67f 100644 --- a/headers/media_plugin/media/openmax/OMX_AsString.h +++ b/headers/media_plugin/media/openmax/OMX_AsString.h @@ -535,6 +535,7 @@ inline static const char *asString(OMX_INDEXEXTTYPE i, const char *def = "??") { // case OMX_IndexConfigCommit: return "ConfigCommit"; case OMX_IndexConfigAndroidVendorExtension: return "ConfigAndroidVendorExtension"; case OMX_IndexParamAudioAndroidAc3: return "ParamAudioAndroidAc3"; + case OMX_IndexConfigAudioPresentation: return "ConfigAudioPresentation"; case OMX_IndexParamAudioAndroidOpus: return "ParamAudioAndroidOpus"; case OMX_IndexParamAudioAndroidAacPresentation: return "ParamAudioAndroidAacPresentation"; case OMX_IndexParamAudioAndroidEac3: return "ParamAudioAndroidEac3"; diff --git a/headers/media_plugin/media/openmax/OMX_AudioExt.h b/headers/media_plugin/media/openmax/OMX_AudioExt.h index 1ea740fbdf..477faedef8 100644 --- a/headers/media_plugin/media/openmax/OMX_AudioExt.h +++ b/headers/media_plugin/media/openmax/OMX_AudioExt.h @@ -127,6 +127,13 @@ typedef struct OMX_AUDIO_PARAM_ANDROID_PROFILETYPE { OMX_U32 nProfileIndex; /**< Used to query for individual profile support information */ } OMX_AUDIO_PARAM_ANDROID_PROFILETYPE; +typedef struct OMX_AUDIO_CONFIG_ANDROID_AUDIOPRESENTATION { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 nPresentationId; /**< presentation id */ + OMX_S32 nProgramId; /**< program id */ +} OMX_AUDIO_CONFIG_ANDROID_AUDIOPRESENTATION; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/headers/media_plugin/media/openmax/OMX_IndexExt.h b/headers/media_plugin/media/openmax/OMX_IndexExt.h index 9fc3ef344e..479e9b8714 100644 --- a/headers/media_plugin/media/openmax/OMX_IndexExt.h +++ b/headers/media_plugin/media/openmax/OMX_IndexExt.h @@ -65,6 +65,7 @@ typedef enum OMX_INDEXEXTTYPE { OMX_IndexParamAudioProfileQuerySupported, /**< reference: OMX_AUDIO_PARAM_ANDROID_PROFILETYPE */ OMX_IndexParamAudioAndroidAacDrcPresentation, /**< reference: OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE */ OMX_IndexParamAudioAndroidAc4, /**< reference: OMX_AUDIO_PARAM_ANDROID_AC4TYPE */ + OMX_IndexConfigAudioPresentation, /**< reference: OMX_AUDIO_CONFIG_ANDROID_AUDIOPRESENTATION */ OMX_IndexExtAudioEndUnused, /* Image parameters and configurations */ diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h index 4d24680246..ed9531ec62 100644 --- a/include/android/multinetwork.h +++ b/include/android/multinetwork.h @@ -110,6 +110,47 @@ int android_getaddrinfofornetwork(net_handle_t network, #endif /* __ANDROID_API__ >= 23 */ +#if __ANDROID_API__ >= 29 + +/** + * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated + * with Domain Name |dname| on the given |network|. + * The typical value for |ns_class| is ns_c_in, while |type| can be any + * record type (for instance, ns_t_aaaa or ns_t_txt). + * + * Returns a file descriptor to watch for read events, or a negative + * POSIX error code (see errno.h) if an immediate error occurs. + */ +int android_res_nquery(net_handle_t network, + const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29); + +/** + * Issue the query |msg| on the given |network|. + * + * Returns a file descriptor to watch for read events, or a negative + * POSIX error code (see errno.h) if an immediate error occurs. + */ +int android_res_nsend(net_handle_t network, + const unsigned char *msg, int msglen) __INTRODUCED_IN(29); + +/** + * Read a result for the query associated with the |fd| descriptor. + * + * Returns: + * < 0: negative POSIX error code (see errno.h for possible values). |rcode| is not set. + * >= 0: length of |answer|. |rcode| is the resolver return code (e.g., ns_r_nxdomain) + */ +int android_res_nresult(int fd, + int *rcode, unsigned char *answer, int anslen) __INTRODUCED_IN(29); + +/** + * Attempts to cancel the in-progress query associated with the |nsend_fd| + * descriptor. + */ +void android_res_cancel(int nsend_fd) __INTRODUCED_IN(29); + +#endif /* __ANDROID_API__ >= 29 */ + __END_DECLS #endif // ANDROID_MULTINETWORK_H diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index d799c5f0c6..dc4e000766 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -40,6 +40,10 @@ cc_library { ], version_script: "libbinder_ndk.map.txt", + stubs: { + symbol_file: "libbinder_ndk.map.txt", + versions: ["29"], + }, } ndk_headers { diff --git a/libs/binder/tests/binderValueTypeTest.cpp b/libs/binder/tests/binderValueTypeTest.cpp index 15949d48c0..f8922b0784 100644 --- a/libs/binder/tests/binderValueTypeTest.cpp +++ b/libs/binder/tests/binderValueTypeTest.cpp @@ -75,13 +75,13 @@ using ::std::vector; VALUE_TYPE_TEST(bool, Boolean, true) VALUE_TYPE_TEST(int32_t, Int, 31337) -VALUE_TYPE_TEST(int64_t, Long, 13370133701337l) +VALUE_TYPE_TEST(int64_t, Long, 13370133701337L) VALUE_TYPE_TEST(double, Double, 3.14159265358979323846) VALUE_TYPE_TEST(String16, String, String16("Lovely")) VALUE_TYPE_VECTOR_TEST(bool, Boolean, true) VALUE_TYPE_VECTOR_TEST(int32_t, Int, 31337) -VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337l) +VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337L) VALUE_TYPE_VECTOR_TEST(double, Double, 3.14159265358979323846) VALUE_TYPE_VECTOR_TEST(String16, String, String16("Lovely")) diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 5cf05ae891..2d6be26903 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -1029,7 +1029,7 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(static_cast<int32_t>(defaultDataspace)); reply->writeInt32(static_cast<int32_t>(defaultPixelFormat)); reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace)); - reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace)); + reply->writeInt32(static_cast<int32_t>(wideColorGamutPixelFormat)); } return NO_ERROR; } diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp index 3816c1bc4f..36eaed93ad 100644 --- a/libs/ui/BufferHubBuffer.cpp +++ b/libs/ui/BufferHubBuffer.cpp @@ -40,6 +40,7 @@ #include <android-base/unique_fd.h> #include <ui/BufferHubBuffer.h> +#include <ui/BufferHubDefs.h> using android::base::unique_fd; using android::dvr::BufferTraits; @@ -69,7 +70,6 @@ using dvr::BufferHubDefs::IsClientGained; using dvr::BufferHubDefs::IsClientPosted; using dvr::BufferHubDefs::IsClientReleased; using dvr::BufferHubDefs::kHighBitsMask; -using dvr::BufferHubDefs::kMetadataHeaderSize; } // namespace @@ -161,7 +161,7 @@ int BufferHubBuffer::ImportGraphicBuffer() { } size_t metadataSize = static_cast<size_t>(bufferTraits.metadata_size()); - if (metadataSize < kMetadataHeaderSize) { + if (metadataSize < BufferHubDefs::kMetadataHeaderSize) { ALOGE("BufferHubBuffer::ImportGraphicBuffer: metadata too small: %zu", metadataSize); return -EINVAL; } diff --git a/libs/ui/BufferHubMetadata.cpp b/libs/ui/BufferHubMetadata.cpp index 18d9a2c963..816707db9d 100644 --- a/libs/ui/BufferHubMetadata.cpp +++ b/libs/ui/BufferHubMetadata.cpp @@ -16,6 +16,7 @@ #include <errno.h> #include <sys/mman.h> +#include <limits> #include <cutils/ashmem.h> #include <log/log.h> @@ -29,8 +30,8 @@ static const int kAshmemProt = PROT_READ | PROT_WRITE; } // namespace -using dvr::BufferHubDefs::kMetadataHeaderSize; -using dvr::BufferHubDefs::MetadataHeader; +using BufferHubDefs::kMetadataHeaderSize; +using BufferHubDefs::MetadataHeader; /* static */ BufferHubMetadata BufferHubMetadata::Create(size_t userMetadataSize) { diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h new file mode 100644 index 0000000000..ef6668bd76 --- /dev/null +++ b/libs/ui/include/ui/BufferHubDefs.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BUFFER_HUB_DEFS_H_ +#define ANDROID_BUFFER_HUB_DEFS_H_ + +#include <atomic> + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpacked" +// TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr +#include <dvr/dvr_api.h> +#pragma clang diagnostic pop + +namespace android { + +namespace BufferHubDefs { + +// Single buffer clients (up to 32) ownership signal. +// 64-bit atomic unsigned int. +// Each client takes 2 bits. The first bit locates in the first 32 bits of +// buffer_state; the second bit locates in the last 32 bits of buffer_state. +// Client states: +// Gained state 11. Exclusive write state. +// Posted state 10. +// Acquired state 01. Shared read state. +// Released state 00. +// +// MSB LSB +// | | +// v v +// [C31|...|C1|C0|C31| ... |C1|C0] + +// Maximum number of clients a buffer can have. +static constexpr int kMaxNumberOfClients = 32; + +// Definition of bit masks. +// MSB LSB +// | kHighBitsMask | kLowbitsMask | +// v v v +// [b63| ... |b32|b31| ... |b0] + +// The location of lower 32 bits in the 64-bit buffer state. +static constexpr uint64_t kLowbitsMask = (1ULL << kMaxNumberOfClients) - 1ULL; + +// The location of higher 32 bits in the 64-bit buffer state. +static constexpr uint64_t kHighBitsMask = ~kLowbitsMask; + +// The client bit mask of the first client. +static constexpr uint64_t kFirstClientBitMask = (1ULL << kMaxNumberOfClients) + 1ULL; + +// Returns true if any of the client is in gained state. +static inline bool AnyClientGained(uint64_t state) { + uint64_t high_bits = state >> kMaxNumberOfClients; + uint64_t low_bits = state & kLowbitsMask; + return high_bits == low_bits && low_bits != 0ULL; +} + +// Returns true if the input client is in gained state. +static inline bool IsClientGained(uint64_t state, uint64_t client_bit_mask) { + return state == client_bit_mask; +} + +// Returns true if any of the client is in posted state. +static inline bool AnyClientPosted(uint64_t state) { + uint64_t high_bits = state >> kMaxNumberOfClients; + uint64_t low_bits = state & kLowbitsMask; + uint64_t posted_or_acquired = high_bits ^ low_bits; + return posted_or_acquired & high_bits; +} + +// Returns true if the input client is in posted state. +static inline bool IsClientPosted(uint64_t state, uint64_t client_bit_mask) { + uint64_t client_bits = state & client_bit_mask; + if (client_bits == 0ULL) return false; + uint64_t low_bits = client_bits & kLowbitsMask; + return low_bits == 0ULL; +} + +// Return true if any of the client is in acquired state. +static inline bool AnyClientAcquired(uint64_t state) { + uint64_t high_bits = state >> kMaxNumberOfClients; + uint64_t low_bits = state & kLowbitsMask; + uint64_t posted_or_acquired = high_bits ^ low_bits; + return posted_or_acquired & low_bits; +} + +// Return true if the input client is in acquired state. +static inline bool IsClientAcquired(uint64_t state, uint64_t client_bit_mask) { + uint64_t client_bits = state & client_bit_mask; + if (client_bits == 0ULL) return false; + uint64_t high_bits = client_bits & kHighBitsMask; + return high_bits == 0ULL; +} + +// Returns true if all clients are in released state. +static inline bool IsBufferReleased(uint64_t state) { + return state == 0ULL; +} + +// Returns true if the input client is in released state. +static inline bool IsClientReleased(uint64_t state, uint64_t client_bit_mask) { + return (state & client_bit_mask) == 0ULL; +} + +// Returns the next available buffer client's client_state_masks. +// @params union_bits. Union of all existing clients' client_state_masks. +static inline uint64_t FindNextAvailableClientStateMask(uint64_t union_bits) { + uint64_t low_union = union_bits & kLowbitsMask; + if (low_union == kLowbitsMask) return 0ULL; + uint64_t incremented = low_union + 1ULL; + uint64_t difference = incremented ^ low_union; + uint64_t new_low_bit = (difference + 1ULL) >> 1; + return new_low_bit + (new_low_bit << kMaxNumberOfClients); +} + +struct __attribute__((aligned(8))) MetadataHeader { + // Internal data format, which can be updated as long as the size, padding and field alignment + // of the struct is consistent within the same ABI. As this part is subject for future updates, + // it's not stable cross Android version, so don't have it visible from outside of the Android + // platform (include Apps and vendor HAL). + + // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in + // buffer_state. + std::atomic<uint64_t> buffer_state; + + // Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32 + // bits are there for easier manipulation, but the value should be ignored. + std::atomic<uint64_t> fence_state; + + // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in + // active_clients_bit_mask. + std::atomic<uint64_t> active_clients_bit_mask; + + // The index of the buffer queue where the buffer belongs to. + uint64_t queue_index; + + // Public data format, which should be updated with caution. See more details in dvr_api.h + DvrNativeBufferMetadata metadata; +}; + +static_assert(sizeof(MetadataHeader) == 136, "Unexpected MetadataHeader size"); +static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader); + +} // namespace BufferHubDefs + +} // namespace android + +#endif // ANDROID_BUFFER_HUB_DEFS_H_ diff --git a/libs/ui/include/ui/BufferHubMetadata.h b/libs/ui/include/ui/BufferHubMetadata.h index 4261971f55..212189497a 100644 --- a/libs/ui/include/ui/BufferHubMetadata.h +++ b/libs/ui/include/ui/BufferHubMetadata.h @@ -17,26 +17,8 @@ #ifndef ANDROID_BUFFER_HUB_METADATA_H_ #define ANDROID_BUFFER_HUB_METADATA_H_ -// We would eliminate the clang warnings introduced by libdpx. -// TODO(b/112338294): Remove those once BufferHub moved to use Binder -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wdouble-promotion" -#pragma clang diagnostic ignored "-Wgnu-case-range" -#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" -#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" -#pragma clang diagnostic ignored "-Wnested-anon-types" -#pragma clang diagnostic ignored "-Wpacked" -#pragma clang diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wswitch-enum" -#pragma clang diagnostic ignored "-Wundefined-func-template" -#pragma clang diagnostic ignored "-Wunused-template" -#pragma clang diagnostic ignored "-Wweak-vtables" -#include <private/dvr/buffer_hub_defs.h> -#pragma clang diagnostic pop - #include <android-base/unique_fd.h> +#include <ui/BufferHubDefs.h> namespace android { @@ -84,23 +66,21 @@ public: bool IsValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; } size_t user_metadata_size() const { return mUserMetadataSize; } - size_t metadata_size() const { - return mUserMetadataSize + dvr::BufferHubDefs::kMetadataHeaderSize; - } + size_t metadata_size() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; } const unique_fd& ashmem_fd() const { return mAshmemFd; } - dvr::BufferHubDefs::MetadataHeader* metadata_header() { return mMetadataHeader; } + BufferHubDefs::MetadataHeader* metadata_header() { return mMetadataHeader; } private: BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd, - dvr::BufferHubDefs::MetadataHeader* metadataHeader); + BufferHubDefs::MetadataHeader* metadataHeader); BufferHubMetadata(const BufferHubMetadata&) = delete; void operator=(const BufferHubMetadata&) = delete; size_t mUserMetadataSize = 0; unique_fd mAshmemFd; - dvr::BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr; + BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr; }; } // namespace android diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp index 18bbb3e876..c0f4c8916c 100644 --- a/libs/ui/tests/Android.bp +++ b/libs/ui/tests/Android.bp @@ -73,10 +73,9 @@ cc_test { cc_test { name: "BufferHubMetadata_test", - header_libs: ["libbufferhub_headers", "libdvr_headers"], + header_libs: ["libdvr_headers"], shared_libs: [ "libbase", - "libpdx_default_transport", "libui", "libutils", ], diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp index 14422bf987..11f8e57adc 100644 --- a/libs/ui/tests/BufferHubMetadata_test.cpp +++ b/libs/ui/tests/BufferHubMetadata_test.cpp @@ -17,7 +17,7 @@ #include <gtest/gtest.h> #include <ui/BufferHubMetadata.h> -using android::dvr::BufferHubDefs::IsBufferReleased; +using android::BufferHubDefs::IsBufferReleased; namespace android { namespace dvr { diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h index 400def7341..2de36f26a6 100644 --- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h +++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h @@ -8,8 +8,7 @@ #include <pdx/rpc/remote_method.h> #include <pdx/rpc/serializable.h> #include <private/dvr/native_handle_wrapper.h> - -#include <atomic> +#include <ui/BufferHubDefs.h> namespace android { namespace dvr { @@ -20,136 +19,55 @@ static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB; static constexpr uint32_t kMetadataUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; -// Single buffer clients (up to 32) ownership signal. -// 64-bit atomic unsigned int. -// Each client takes 2 bits. The first bit locates in the first 32 bits of -// buffer_state; the second bit locates in the last 32 bits of buffer_state. -// Client states: -// Gained state 11. Exclusive write state. -// Posted state 10. -// Acquired state 01. Shared read state. -// Released state 00. -// -// MSB LSB -// | | -// v v -// [C31|...|C1|C0|C31| ... |C1|C0] - -// Maximum number of clients a buffer can have. -static constexpr int kMaxNumberOfClients = 32; - -// Definition of bit masks. -// MSB LSB -// | kHighBitsMask | kLowbitsMask | -// v v v -// [b63| ... |b32|b31| ... |b0] - -// The location of lower 32 bits in the 64-bit buffer state. -static constexpr uint64_t kLowbitsMask = (1ULL << kMaxNumberOfClients) - 1ULL; - -// The location of higher 32 bits in the 64-bit buffer state. -static constexpr uint64_t kHighBitsMask = ~kLowbitsMask; - -// The client bit mask of the first client. +// See more details in libs/ui/include/ui/BufferHubDefs.h +static constexpr int kMaxNumberOfClients = + android::BufferHubDefs::kMaxNumberOfClients; +static constexpr uint64_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask; +static constexpr uint64_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask; static constexpr uint64_t kFirstClientBitMask = - (1ULL << kMaxNumberOfClients) + 1ULL; + android::BufferHubDefs::kFirstClientBitMask; -// Returns true if any of the client is in gained state. static inline bool AnyClientGained(uint64_t state) { - uint64_t high_bits = state >> kMaxNumberOfClients; - uint64_t low_bits = state & kLowbitsMask; - return high_bits == low_bits && low_bits != 0ULL; + return android::BufferHubDefs::AnyClientGained(state); } -// Returns true if the input client is in gained state. static inline bool IsClientGained(uint64_t state, uint64_t client_bit_mask) { - return state == client_bit_mask; + return android::BufferHubDefs::IsClientGained(state, client_bit_mask); } -// Returns true if any of the client is in posted state. static inline bool AnyClientPosted(uint64_t state) { - uint64_t high_bits = state >> kMaxNumberOfClients; - uint64_t low_bits = state & kLowbitsMask; - uint64_t posted_or_acquired = high_bits ^ low_bits; - return posted_or_acquired & high_bits; + return android::BufferHubDefs::AnyClientPosted(state); } -// Returns true if the input client is in posted state. static inline bool IsClientPosted(uint64_t state, uint64_t client_bit_mask) { - uint64_t client_bits = state & client_bit_mask; - if (client_bits == 0ULL) - return false; - uint64_t low_bits = client_bits & kLowbitsMask; - return low_bits == 0ULL; + return android::BufferHubDefs::IsClientPosted(state, client_bit_mask); } -// Return true if any of the client is in acquired state. static inline bool AnyClientAcquired(uint64_t state) { - uint64_t high_bits = state >> kMaxNumberOfClients; - uint64_t low_bits = state & kLowbitsMask; - uint64_t posted_or_acquired = high_bits ^ low_bits; - return posted_or_acquired & low_bits; + return android::BufferHubDefs::AnyClientAcquired(state); } -// Return true if the input client is in acquired state. static inline bool IsClientAcquired(uint64_t state, uint64_t client_bit_mask) { - uint64_t client_bits = state & client_bit_mask; - if (client_bits == 0ULL) - return false; - uint64_t high_bits = client_bits & kHighBitsMask; - return high_bits == 0ULL; + return android::BufferHubDefs::IsClientAcquired(state, client_bit_mask); } -// Returns true if all clients are in released state. -static inline bool IsBufferReleased(uint64_t state) { return state == 0ULL; } +static inline bool IsBufferReleased(uint64_t state) { + return android::BufferHubDefs::IsBufferReleased(state); +} -// Returns true if the input client is in released state. static inline bool IsClientReleased(uint64_t state, uint64_t client_bit_mask) { - return (state & client_bit_mask) == 0ULL; + return android::BufferHubDefs::IsClientReleased(state, client_bit_mask); } // Returns the next available buffer client's client_state_masks. // @params union_bits. Union of all existing clients' client_state_masks. static inline uint64_t FindNextAvailableClientStateMask(uint64_t union_bits) { - uint64_t low_union = union_bits & kLowbitsMask; - if (low_union == kLowbitsMask) - return 0ULL; - uint64_t incremented = low_union + 1ULL; - uint64_t difference = incremented ^ low_union; - uint64_t new_low_bit = (difference + 1ULL) >> 1; - return new_low_bit + (new_low_bit << kMaxNumberOfClients); + return android::BufferHubDefs::FindNextAvailableClientStateMask(union_bits); } -struct __attribute__((packed, aligned(8))) MetadataHeader { - // Internal data format, which can be updated as long as the size, padding and - // field alignment of the struct is consistent within the same ABI. As this - // part is subject for future updates, it's not stable cross Android version, - // so don't have it visible from outside of the Android platform (include Apps - // and vendor HAL). - - // Every client takes up one bit from the higher 32 bits and one bit from the - // lower 32 bits in buffer_state. - std::atomic<uint64_t> buffer_state; - - // Every client takes up one bit in fence_state. Only the lower 32 bits are - // valid. The upper 32 bits are there for easier manipulation, but the value - // should be ignored. - std::atomic<uint64_t> fence_state; - - // Every client takes up one bit from the higher 32 bits and one bit from the - // lower 32 bits in active_clients_bit_mask. - std::atomic<uint64_t> active_clients_bit_mask; - - // The index of the buffer queue where the buffer belongs to. - uint64_t queue_index; - - // Public data format, which should be updated with caution. See more details - // in dvr_api.h - DvrNativeBufferMetadata metadata; -}; - -static_assert(sizeof(MetadataHeader) == 136, "Unexpected MetadataHeader size"); -static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader); +using MetadataHeader = android::BufferHubDefs::MetadataHeader; +static constexpr size_t kMetadataHeaderSize = + android::BufferHubDefs::kMetadataHeaderSize; } // namespace BufferHubDefs diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h index fef8512266..a204f62fff 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api.h +++ b/libs/vr/libdvr/include/dvr/dvr_api.h @@ -412,6 +412,7 @@ typedef int (*DvrTrackingSensorsStopPtr)(DvrTrackingSensors* sensors); // existing data members. If new fields need to be added, please take extra care // to make sure that new data field is padded properly the size of the struct // stays same. +// TODO(b/118893702): move the definition to libnativewindow or libui struct ALIGNED_DVR_STRUCT(8) DvrNativeBufferMetadata { #ifdef __cplusplus DvrNativeBufferMetadata() diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp index fa0adf0182..f72dabc658 100644 --- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp +++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp @@ -66,7 +66,7 @@ void SetThreadName(const std::string& name) { prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0); } -constexpr uint64_t kNanosPerSecond = 1000000000llu; +constexpr uint64_t kNanosPerSecond = 1000000000LLU; uint64_t GetClockNs() { timespec t; diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp index 583aec9db5..c80b79a319 100644 --- a/opengl/libs/Android.bp +++ b/opengl/libs/Android.bp @@ -197,6 +197,7 @@ cc_library_shared { defaults: ["gles_libs_defaults"], srcs: ["GLES_CM/gl.cpp"], cflags: ["-DLOG_TAG=\"libGLESv1\""], + version_script: "libGLESv1_CM.map.txt", } //############################################################################## diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp index f9aaa2050f..72d210cbb0 100644 --- a/services/bufferhub/Android.bp +++ b/services/bufferhub/Android.bp @@ -29,10 +29,8 @@ cc_library_shared { "BufferNode.cpp", ], header_libs: [ - "libbufferhub_headers", "libdvr_headers", "libnativewindow_headers", - "libpdx_headers", ], shared_libs: [ "android.frameworks.bufferhub@1.0", @@ -56,10 +54,8 @@ cc_binary { "main_bufferhub.cpp" ], header_libs: [ - "libbufferhub_headers", "libdvr_headers", "libnativewindow_headers", - "libpdx_headers", ], shared_libs: [ "android.frameworks.bufferhub@1.0", diff --git a/services/bufferhub/BufferClient.cpp b/services/bufferhub/BufferClient.cpp index 745951745a..e312011696 100644 --- a/services/bufferhub/BufferClient.cpp +++ b/services/bufferhub/BufferClient.cpp @@ -17,6 +17,7 @@ #include <bufferhub/BufferClient.h> #include <bufferhub/BufferHubService.h> #include <hidl/HidlSupport.h> +#include <log/log.h> namespace android { namespace frameworks { diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp index ec84849e22..4bad829210 100644 --- a/services/bufferhub/BufferNode.cpp +++ b/services/bufferhub/BufferNode.cpp @@ -2,7 +2,6 @@ #include <bufferhub/BufferHubService.h> #include <bufferhub/BufferNode.h> -#include <private/dvr/buffer_hub_defs.h> #include <ui/GraphicBufferAllocator.h> namespace android { @@ -14,7 +13,7 @@ namespace implementation { void BufferNode::InitializeMetadata() { // Using placement new here to reuse shared memory instead of new allocation // Initialize the atomic variables to zero. - dvr::BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header(); + BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header(); buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0); fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0); active_clients_bit_mask_ = @@ -84,10 +83,11 @@ uint64_t BufferNode::AddNewActiveClientsBitToMask() { uint64_t client_state_mask = 0ULL; uint64_t updated_active_clients_bit_mask = 0ULL; do { - client_state_mask = dvr::BufferHubDefs::FindNextAvailableClientStateMask( - current_active_clients_bit_mask); + client_state_mask = + BufferHubDefs::FindNextAvailableClientStateMask(current_active_clients_bit_mask); if (client_state_mask == 0ULL) { - ALOGE("%s: reached the maximum number of channels per buffer node: 32.", __FUNCTION__); + ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__, + BufferHubDefs::kMaxNumberOfClients); errno = E2BIG; return 0ULL; } diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h index 94ef505d41..02bb5af0e0 100644 --- a/services/bufferhub/include/bufferhub/BufferNode.h +++ b/services/bufferhub/include/bufferhub/BufferNode.h @@ -3,6 +3,7 @@ #include <android/hardware_buffer.h> #include <bufferhub/BufferHubIdGenerator.h> +#include <cutils/native_handle.h> #include <ui/BufferHubMetadata.h> namespace android { diff --git a/services/bufferhub/tests/Android.bp b/services/bufferhub/tests/Android.bp index 39678865cb..bf65469784 100644 --- a/services/bufferhub/tests/Android.bp +++ b/services/bufferhub/tests/Android.bp @@ -7,10 +7,8 @@ cc_test { "-DATRACE_TAG=ATRACE_TAG_GRAPHICS", ], header_libs: [ - "libbufferhub_headers", "libdvr_headers", "libnativewindow_headers", - "libpdx_headers", ], shared_libs: [ "libbufferhubservice", @@ -19,8 +17,6 @@ cc_test { static_libs: [ "libgmock", ], - // TODO(b/117568153): Temporarily opt out using libcrt. - no_libcrt: true, } cc_test { diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp index df31d78b89..8555eb7800 100644 --- a/services/bufferhub/tests/BufferNode_test.cpp +++ b/services/bufferhub/tests/BufferNode_test.cpp @@ -1,7 +1,9 @@ -#include <bufferhub/BufferNode.h> #include <errno.h> + +#include <bufferhub/BufferNode.h> #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <ui/BufferHubDefs.h> #include <ui/GraphicBufferMapper.h> namespace android { @@ -20,7 +22,6 @@ const uint32_t kLayerCount = 1; const uint32_t kFormat = 1; const uint64_t kUsage = 0; const size_t kUserMetadataSize = 0; -const size_t kMaxClientsCount = dvr::BufferHubDefs::kMaxNumberOfClients; class BufferNodeTest : public ::testing::Test { protected: @@ -71,7 +72,7 @@ TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_32NewClients) { uint64_t current_mask = 0ULL; uint64_t expected_mask = 0ULL; - for (int i = 0; i < kMaxClientsCount; ++i) { + for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) { new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask(); EXPECT_NE(new_client_state_mask, 0); EXPECT_FALSE(new_client_state_mask & current_mask); diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4e4d7dd371..0a3be71b79 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -396,6 +396,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime } // Capture the old state of the layer for comparisons later + Mutex::Autolock lock(mStateMutex); const State& s(getDrawingState()); const bool oldOpacity = isOpaque(s); sp<GraphicBuffer> oldBuffer = mActiveBuffer; @@ -502,7 +503,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // FIXME: postedRegion should be dirty & bounds // transform the dirty region to window-manager space - return getTransform().transform(Region(getBufferSize(s))); + return getTransformLocked().transform(Region(getBufferSize(s))); } // transaction @@ -550,7 +551,7 @@ bool BufferLayer::latchUnsignaledBuffers() { // h/w composer set-up bool BufferLayer::allTransactionsSignaled() { - auto headFrameNumber = getHeadFrameNumber(); + auto headFrameNumber = getHeadFrameNumberLocked(); bool matchingFramesFound = false; bool allTransactionsApplied = true; Mutex::Autolock lock(mLocalSyncPointMutex); @@ -603,6 +604,7 @@ bool BufferLayer::needsFiltering(const RenderArea& renderArea) const { void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const { ATRACE_CALL(); + Mutex::Autolock lock(mStateMutex); const State& s(getDrawingState()); computeGeometry(renderArea, getBE().mMesh, useIdentityTransform); @@ -621,9 +623,9 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT * minimal value)? Or, we could make GL behave like HWC -- but this feel * like more of a hack. */ - const Rect bounds{computeBounds()}; // Rounds from FloatRect + const Rect bounds{computeBoundsLocked()}; // Rounds from FloatRect - ui::Transform t = getTransform(); + ui::Transform t = getTransformLocked(); Rect win = bounds; const int bufferWidth = getBufferSize(s).getWidth(); const int bufferHeight = getBufferSize(s).getHeight(); @@ -642,7 +644,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT texCoords[2] = vec2(right, 1.0f - bottom); texCoords[3] = vec2(right, 1.0f - top); - const auto roundedCornerState = getRoundedCornerState(); + const auto roundedCornerState = getRoundedCornerStateLocked(); const auto cropRect = roundedCornerState.cropRect; setupRoundedCornersCropCoordinates(win, cropRect); @@ -664,7 +666,12 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT } uint64_t BufferLayer::getHeadFrameNumber() const { - if (hasFrameUpdate()) { + Mutex::Autolock lock(mStateMutex); + return getHeadFrameNumberLocked(); +} + +uint64_t BufferLayer::getHeadFrameNumberLocked() const { + if (hasFrameUpdateLocked()) { return getFrameNumber(); } else { return mCurrentFrameNumber; @@ -691,7 +698,7 @@ Rect BufferLayer::getBufferSize(const State& s) const { std::swap(bufWidth, bufHeight); } - if (getTransformToDisplayInverse()) { + if (getTransformToDisplayInverseLocked()) { uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); if (invTransform & ui::Transform::ROT_90) { std::swap(bufWidth, bufHeight); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 690a4e5b3c..55d68f691a 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -69,7 +69,7 @@ public: bool isOpaque(const Layer::State& s) const override; // isVisible - true if this layer is visible, false otherwise - bool isVisible() const override; + bool isVisible() const override EXCLUDES(mStateMutex); // isFixedSize - true if content has a fixed size bool isFixedSize() const override; @@ -87,7 +87,7 @@ public: bool onPostComposition(const std::optional<DisplayId>& displayId, const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, - const CompositorTiming& compositorTiming) override; + const CompositorTiming& compositorTiming) override EXCLUDES(mStateMutex); // latchBuffer - called each time the screen is redrawn and returns whether // the visible regions need to be recomputed (this is a fairly heavy @@ -97,13 +97,13 @@ public: // releaseFence will be populated with a native fence that fires when // composition has completed. Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, - const sp<Fence>& releaseFence) override; + const sp<Fence>& releaseFence) override EXCLUDES(mStateMutex); bool isBufferLatched() const override { return mRefreshPending; } void notifyAvailableFrames() override; - bool hasReadyFrame() const override; + bool hasReadyFrame() const override EXCLUDES(mStateMutex); // Returns the current scaling mode, unless mOverrideScalingMode // is set, in which case, it returns mOverrideScalingMode @@ -114,19 +114,24 @@ public: // Functions that must be implemented by derived classes // ----------------------------------------------------------------------- private: - virtual bool fenceHasSignaled() const = 0; + virtual bool fenceHasSignaled() const EXCLUDES(mStateMutex) = 0; virtual nsecs_t getDesiredPresentTime() = 0; - virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0; + std::shared_ptr<FenceTime> getCurrentFenceTime() const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return getCurrentFenceTimeLocked(); + } + + virtual std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const REQUIRES(mStateMutex) = 0; virtual void getDrawingTransformMatrix(float *matrix) = 0; - virtual uint32_t getDrawingTransform() const = 0; - virtual ui::Dataspace getDrawingDataSpace() const = 0; - virtual Rect getDrawingCrop() const = 0; + virtual uint32_t getDrawingTransform() const REQUIRES(mStateMutex) = 0; + virtual ui::Dataspace getDrawingDataSpace() const REQUIRES(mStateMutex) = 0; + virtual Rect getDrawingCrop() const REQUIRES(mStateMutex) = 0; virtual uint32_t getDrawingScalingMode() const = 0; - virtual Region getDrawingSurfaceDamage() const = 0; - virtual const HdrMetadata& getDrawingHdrMetadata() const = 0; - virtual int getDrawingApi() const = 0; + virtual Region getDrawingSurfaceDamage() const EXCLUDES(mStateMutex) = 0; + virtual const HdrMetadata& getDrawingHdrMetadata() const EXCLUDES(mStateMutex) = 0; + virtual int getDrawingApi() const EXCLUDES(mStateMutex) = 0; virtual PixelFormat getPixelFormat() const = 0; virtual uint64_t getFrameNumber() const = 0; @@ -134,20 +139,21 @@ private: virtual bool getAutoRefresh() const = 0; virtual bool getSidebandStreamChanged() const = 0; - virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0; + virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) + EXCLUDES(mStateMutex) = 0; - virtual bool hasFrameUpdate() const = 0; + virtual bool hasFrameUpdateLocked() const REQUIRES(mStateMutex) = 0; virtual void setFilteringEnabled(bool enabled) = 0; - virtual status_t bindTextureImage() = 0; + virtual status_t bindTextureImage() EXCLUDES(mStateMutex) = 0; virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, - const sp<Fence>& flushFence) = 0; + const sp<Fence>& flushFence) REQUIRES(mStateMutex) = 0; - virtual status_t updateActiveBuffer() = 0; + virtual status_t updateActiveBuffer() REQUIRES(mStateMutex) = 0; virtual status_t updateFrameNumber(nsecs_t latchTime) = 0; - virtual void setHwcLayerBuffer(DisplayId displayId) = 0; + virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0; // ----------------------------------------------------------------------- @@ -163,10 +169,15 @@ protected: // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to // be latched have signaled - bool allTransactionsSignaled(); + bool allTransactionsSignaled() REQUIRES(mStateMutex); static bool getOpacityForFormat(uint32_t format); + bool hasFrameUpdate() const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return hasFrameUpdateLocked(); + } + // from GLES const uint32_t mTextureName; @@ -175,9 +186,12 @@ private: bool needsFiltering(const RenderArea& renderArea) const; // drawing - void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const; + void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const + EXCLUDES(mStateMutex); + + uint64_t getHeadFrameNumber() const EXCLUDES(mStateMutex); - uint64_t getHeadFrameNumber() const; + uint64_t getHeadFrameNumberLocked() const REQUIRES(mStateMutex); uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE}; @@ -189,7 +203,7 @@ private: bool mRefreshPending{false}; - Rect getBufferSize(const State& s) const override; + Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex); }; } // namespace android diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index b784d1195d..70d52f1848 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -51,7 +51,7 @@ std::vector<OccupancyTracker::Segment> BufferQueueLayer::getOccupancyHistory(boo return history; } -bool BufferQueueLayer::getTransformToDisplayInverse() const { +bool BufferQueueLayer::getTransformToDisplayInverseLocked() const { return mConsumer->getTransformToDisplayInverse(); } @@ -131,7 +131,7 @@ nsecs_t BufferQueueLayer::getDesiredPresentTime() { return mConsumer->getTimestamp(); } -std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const { +std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTimeLocked() const { return mConsumer->getCurrentFenceTime(); } @@ -192,6 +192,7 @@ bool BufferQueueLayer::getSidebandStreamChanged() const { std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) { bool sidebandStreamChanged = true; + Mutex::Autolock lock(mStateMutex); if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) { // mSidebandStreamChanged was changed to false // replicated in LayerBE until FE/BE is ready to be synchronized @@ -200,15 +201,15 @@ std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisib setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } - recomputeVisibleRegions = true; + recomputeVisibleRegions = true; const State& s(getDrawingState()); - return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h))); + return getTransformLocked().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h))); } return {}; } -bool BufferQueueLayer::hasFrameUpdate() const { +bool BufferQueueLayer::hasFrameUpdateLocked() const { return mQueuedFrames > 0; } @@ -228,16 +229,18 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t // buffer mode. bool queuedBuffer = false; const int32_t layerID = getSequence(); - LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions, + status_t updateResult; + LayerRejecter r(mState.drawing, getCurrentState(), recomputeVisibleRegions, getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode, - getTransformToDisplayInverse(), mFreezeGeometryUpdates); + getTransformToDisplayInverseLocked(), mFreezeGeometryUpdates); const nsecs_t expectedPresentTime = mFlinger->mUseScheduler ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime() : mFlinger->mPrimaryDispSync->expectedPresentTime(); - status_t updateResult = - mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer, - mLastFrameNumberReceived, releaseFence); + + updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer, + mLastFrameNumberReceived, releaseFence); + if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index ae0b7054c0..f9da044b83 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -44,7 +44,7 @@ public: std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override; - bool getTransformToDisplayInverse() const override; + bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex); // If a buffer was replaced this frame, release the former buffer void releasePendingBuffer(nsecs_t dequeueReadyTime) override; @@ -64,12 +64,12 @@ public: private: nsecs_t getDesiredPresentTime() override; - std::shared_ptr<FenceTime> getCurrentFenceTime() const override; + std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex); void getDrawingTransformMatrix(float *matrix) override; - uint32_t getDrawingTransform() const override; - ui::Dataspace getDrawingDataSpace() const override; - Rect getDrawingCrop() const override; + uint32_t getDrawingTransform() const override REQUIRES(mStateMutex); + ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex); + Rect getDrawingCrop() const override REQUIRES(mStateMutex); uint32_t getDrawingScalingMode() const override; Region getDrawingSurfaceDamage() const override; const HdrMetadata& getDrawingHdrMetadata() const override; @@ -81,17 +81,18 @@ private: bool getAutoRefresh() const override; bool getSidebandStreamChanged() const override; - std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override; + std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override + EXCLUDES(mStateMutex); - bool hasFrameUpdate() const override; + bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex); void setFilteringEnabled(bool enabled) override; status_t bindTextureImage() override; status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, - const sp<Fence>& releaseFence) override; + const sp<Fence>& releaseFence) override REQUIRES(mStateMutex); - status_t updateActiveBuffer() override; + status_t updateActiveBuffer() override REQUIRES(mStateMutex); status_t updateFrameNumber(nsecs_t latchTime) override; void setHwcLayerBuffer(DisplayId displayId) override; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index efc2c9f7b3..8091b941f8 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -70,30 +70,31 @@ bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const { } bool BufferStateLayer::willPresentCurrentTransaction() const { + Mutex::Autolock lock(mStateMutex); // Returns true if the most recent Transaction applied to CurrentState will be presented. return getSidebandStreamChanged() || getAutoRefresh() || - (mCurrentState.modified && mCurrentState.buffer != nullptr); + (mState.current.modified && mState.current.buffer != nullptr); } -bool BufferStateLayer::getTransformToDisplayInverse() const { - return mCurrentState.transformToDisplayInverse; +bool BufferStateLayer::getTransformToDisplayInverseLocked() const { + return mState.current.transformToDisplayInverse; } -void BufferStateLayer::pushPendingState() { - if (!mCurrentState.modified) { +void BufferStateLayer::pushPendingStateLocked() { + if (!mState.current.modified) { return; } - mPendingStates.push_back(mCurrentState); - ATRACE_INT(mTransactionName.string(), mPendingStates.size()); + mState.pending.push_back(mState.current); + ATRACE_INT(mTransactionName.string(), mState.pending.size()); } bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { - const bool stateUpdateAvailable = !mPendingStates.empty(); - while (!mPendingStates.empty()) { + const bool stateUpdateAvailable = !mState.pending.empty(); + while (!mState.pending.empty()) { popPendingState(stateToCommit); } - mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified; - mCurrentState.modified = false; + mCurrentStateModified = stateUpdateAvailable && mState.current.modified; + mState.current.modified = false; return stateUpdateAvailable; } @@ -103,28 +104,31 @@ Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { } bool BufferStateLayer::setTransform(uint32_t transform) { - if (mCurrentState.transform == transform) return false; - mCurrentState.sequence++; - mCurrentState.transform = transform; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.transform == transform) return false; + mState.current.sequence++; + mState.current.transform = transform; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) { - if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false; - mCurrentState.sequence++; - mCurrentState.transformToDisplayInverse = transformToDisplayInverse; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false; + mState.current.sequence++; + mState.current.transformToDisplayInverse = transformToDisplayInverse; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setCrop(const Rect& crop) { - if (mCurrentState.crop == crop) return false; - mCurrentState.sequence++; - mCurrentState.crop = crop; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.crop == crop) return false; + mState.current.sequence++; + mState.current.crop = crop; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -135,86 +139,94 @@ bool BufferStateLayer::setFrame(const Rect& frame) { int w = frame.getWidth(); int h = frame.getHeight(); - if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y && - mCurrentState.active.w == w && mCurrentState.active.h == h) { + Mutex::Autolock lock(mStateMutex); + if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y && + mState.current.active.w == w && mState.current.active.h == h) { return false; } if (!frame.isValid()) { x = y = w = h = 0; } - mCurrentState.active.transform.set(x, y); - mCurrentState.active.w = w; - mCurrentState.active.h = h; + mState.current.active.transform.set(x, y); + mState.current.active.w = w; + mState.current.active.h = h; - mCurrentState.sequence++; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) { - if (mCurrentState.buffer) { + Mutex::Autolock lock(mStateMutex); + if (mState.current.buffer) { mReleasePreviousBuffer = true; } - mCurrentState.sequence++; - mCurrentState.buffer = buffer; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.buffer = buffer; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) { + Mutex::Autolock lock(mStateMutex); // The acquire fences of BufferStateLayers have already signaled before they are set mCallbackHandleAcquireTime = fence->getSignalTime(); - mCurrentState.acquireFence = fence; - mCurrentState.modified = true; + mState.current.acquireFence = fence; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { - if (mCurrentState.dataspace == dataspace) return false; - mCurrentState.sequence++; - mCurrentState.dataspace = dataspace; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.dataspace == dataspace) return false; + mState.current.sequence++; + mState.current.dataspace = dataspace; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) { - if (mCurrentState.hdrMetadata == hdrMetadata) return false; - mCurrentState.sequence++; - mCurrentState.hdrMetadata = hdrMetadata; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.hdrMetadata == hdrMetadata) return false; + mState.current.sequence++; + mState.current.hdrMetadata = hdrMetadata; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) { - mCurrentState.sequence++; - mCurrentState.surfaceDamageRegion = surfaceDamage; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.sequence++; + mState.current.surfaceDamageRegion = surfaceDamage; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setApi(int32_t api) { - if (mCurrentState.api == api) return false; - mCurrentState.sequence++; - mCurrentState.api = api; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.api == api) return false; + mState.current.sequence++; + mState.current.api = api; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) { - if (mCurrentState.sidebandStream == sidebandStream) return false; - mCurrentState.sequence++; - mCurrentState.sidebandStream = sidebandStream; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.sidebandStream == sidebandStream) return false; + mState.current.sequence++; + mState.current.sidebandStream = sidebandStream; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); if (!mSidebandStreamChanged.exchange(true)) { @@ -248,7 +260,10 @@ bool BufferStateLayer::setTransactionCompletedListeners( mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle); // Store so latched time and release fence can be set - mCurrentState.callbackHandles.push_back(handle); + { + Mutex::Autolock lock(mStateMutex); + mState.current.callbackHandles.push_back(handle); + } } else { // If this layer will NOT need to be relatched and presented this frame // Notify the transaction completed thread this handle is done @@ -263,8 +278,9 @@ bool BufferStateLayer::setTransactionCompletedListeners( } bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { - mCurrentState.transparentRegionHint = transparent; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.transparentRegionHint = transparent; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -300,6 +316,7 @@ bool BufferStateLayer::fenceHasSignaled() const { return true; } + Mutex::Autolock lock(mStateMutex); return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; } @@ -308,7 +325,7 @@ nsecs_t BufferStateLayer::getDesiredPresentTime() { return 0; } -std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const { +std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const { return std::make_shared<FenceTime>(getDrawingState().acquireFence); } @@ -339,14 +356,17 @@ uint32_t BufferStateLayer::getDrawingScalingMode() const { } Region BufferStateLayer::getDrawingSurfaceDamage() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().surfaceDamageRegion; } const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().hdrMetadata; } int BufferStateLayer::getDrawingApi() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().api; } @@ -371,6 +391,7 @@ bool BufferStateLayer::getSidebandStreamChanged() const { } std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { + Mutex::Autolock lock(mStateMutex); if (mSidebandStreamChanged.exchange(false)) { const State& s(getDrawingState()); // mSidebandStreamChanged was true @@ -382,12 +403,12 @@ std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisib } recomputeVisibleRegions = true; - return getTransform().transform(Region(Rect(s.active.w, s.active.h))); + return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h))); } return {}; } -bool BufferStateLayer::hasFrameUpdate() const { +bool BufferStateLayer::hasFrameUpdateLocked() const { return mCurrentStateModified && getCurrentState().buffer != nullptr; } @@ -397,6 +418,10 @@ void BufferStateLayer::setFilteringEnabled(bool enabled) { } status_t BufferStateLayer::bindTextureImage() { + Mutex::Autolock lock(mStateMutex); + return bindTextureImageLocked(); +} +status_t BufferStateLayer::bindTextureImageLocked() { const State& s(getDrawingState()); auto& engine(mFlinger->getRenderEngine()); @@ -501,7 +526,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse auto incomingStatus = releaseFence->getStatus(); if (incomingStatus == Fence::Status::Invalid) { ALOGE("New fence has invalid state"); - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; } @@ -512,16 +537,16 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse char fenceName[32] = {}; snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber); sp<Fence> mergedFence = - Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence); + Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence); if (!mergedFence.get()) { ALOGE("failed to merge release fences"); // synchronization is broken, the best we can do is hope fences // signal in order so the new fence will act like a union - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; } - mDrawingState.acquireFence = mergedFence; + mState.drawing.acquireFence = mergedFence; } else if (incomingStatus == Fence::Status::Unsignaled) { // If one fence has signaled and the other hasn't, the unsignaled // fence will approximately correspond with the correct timestamp. @@ -530,7 +555,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // by this point, they will have both signaled and only the timestamp // will be slightly off; any dependencies after this point will // already have been met. - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; } } else { // Bind the new buffer to the GL texture. @@ -539,7 +564,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // by glEGLImageTargetTexture2DOES, which this method calls. Newer // devices will either call this in Layer::onDraw, or (if it's not // a GL-composited layer) not at all. - status_t err = bindTextureImage(); + status_t err = bindTextureImageLocked(); if (err != NO_ERROR) { mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; @@ -548,7 +573,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // TODO(marissaw): properly support mTimeStats mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime); - mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime()); + mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked()); mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime); return NO_ERROR; @@ -575,6 +600,7 @@ status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) { } void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) { + Mutex::Autolock lock(mStateMutex); auto& hwcInfo = getBE().mHwcLayers[displayId]; auto& hwcLayer = hwcInfo.layer; diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 3f891d3fd6..655353cf3d 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -41,13 +41,14 @@ public: bool shouldPresentNow(nsecs_t expectedPresentTime) const override; - bool getTransformToDisplayInverse() const override; + bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex); uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override { return flags; } - void pushPendingState() override; - bool applyPendingStates(Layer::State* stateToCommit) override; + + void pushPendingStateLocked() override REQUIRES(mStateMutex); + bool applyPendingStates(Layer::State* stateToCommit) override REQUIRES(mStateMutex); uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; } uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; } @@ -59,18 +60,20 @@ public: } Rect getCrop(const Layer::State& s) const; - bool setTransform(uint32_t transform) override; - bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; - bool setCrop(const Rect& crop) override; - bool setFrame(const Rect& frame) override; - bool setBuffer(const sp<GraphicBuffer>& buffer) override; - bool setAcquireFence(const sp<Fence>& fence) override; - bool setDataspace(ui::Dataspace dataspace) override; - bool setHdrMetadata(const HdrMetadata& hdrMetadata) override; - bool setSurfaceDamageRegion(const Region& surfaceDamage) override; - bool setApi(int32_t api) override; - bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override; - bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override; + bool setTransform(uint32_t transform) override EXCLUDES(mStateMutex); + bool setTransformToDisplayInverse(bool transformToDisplayInverse) override + EXCLUDES(mStateMutex); + bool setCrop(const Rect& crop) override EXCLUDES(mStateMutex); + bool setFrame(const Rect& frame) override EXCLUDES(mStateMutex); + bool setBuffer(const sp<GraphicBuffer>& buffer) override EXCLUDES(mStateMutex); + bool setAcquireFence(const sp<Fence>& fence) override EXCLUDES(mStateMutex); + bool setDataspace(ui::Dataspace dataspace) override EXCLUDES(mStateMutex); + bool setHdrMetadata(const HdrMetadata& hdrMetadata) override EXCLUDES(mStateMutex); + bool setSurfaceDamageRegion(const Region& surfaceDamage) override EXCLUDES(mStateMutex); + bool setApi(int32_t api) override EXCLUDES(mStateMutex); + bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override EXCLUDES(mStateMutex); + bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override + EXCLUDES(mStateMutex); // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; } @@ -87,26 +90,26 @@ public: void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/, uint64_t /*frameNumber*/) override {} - Rect getBufferSize(const State& s) const override; + Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex); // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Interface implementation for BufferLayer // ----------------------------------------------------------------------- - bool fenceHasSignaled() const override; + bool fenceHasSignaled() const override EXCLUDES(mStateMutex); private: nsecs_t getDesiredPresentTime() override; - std::shared_ptr<FenceTime> getCurrentFenceTime() const override; + std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex); void getDrawingTransformMatrix(float *matrix) override; - uint32_t getDrawingTransform() const override; - ui::Dataspace getDrawingDataSpace() const override; - Rect getDrawingCrop() const override; + uint32_t getDrawingTransform() const override REQUIRES(mStateMutex); + ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex); + Rect getDrawingCrop() const override REQUIRES(mStateMutex); uint32_t getDrawingScalingMode() const override; - Region getDrawingSurfaceDamage() const override; - const HdrMetadata& getDrawingHdrMetadata() const override; - int getDrawingApi() const override; + Region getDrawingSurfaceDamage() const override EXCLUDES(mStateMutex); + const HdrMetadata& getDrawingHdrMetadata() const override EXCLUDES(mStateMutex); + int getDrawingApi() const override EXCLUDES(mStateMutex); PixelFormat getPixelFormat() const override; uint64_t getFrameNumber() const override; @@ -114,24 +117,26 @@ private: bool getAutoRefresh() const override; bool getSidebandStreamChanged() const override; - std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override; + std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override + EXCLUDES(mStateMutex); - bool hasFrameUpdate() const override; + bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex); void setFilteringEnabled(bool enabled) override; - status_t bindTextureImage() override; + status_t bindTextureImage() override EXCLUDES(mStateMutex); status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, - const sp<Fence>& releaseFence) override; + const sp<Fence>& releaseFence) override REQUIRES(mStateMutex); - status_t updateActiveBuffer() override; + status_t updateActiveBuffer() override REQUIRES(mStateMutex); status_t updateFrameNumber(nsecs_t latchTime) override; - void setHwcLayerBuffer(DisplayId displayId) override; + void setHwcLayerBuffer(DisplayId displayId) override EXCLUDES(mStateMutex); private: void onFirstRef() override; bool willPresentCurrentTransaction() const; + status_t bindTextureImageLocked() REQUIRES(mStateMutex); static const std::array<float, 16> IDENTITY_MATRIX; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index f27f6aa87e..cb7642e60f 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -40,15 +40,16 @@ ColorLayer::~ColorLayer() = default; void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, bool useIdentityTransform) { + Mutex::Autolock lock(mStateMutex); half4 color = getColor(); if (color.a > 0) { renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2); computeGeometry(renderArea, mesh, useIdentityTransform); auto& engine(mFlinger->getRenderEngine()); - Rect win{computeBounds()}; + Rect win{computeBoundsLocked()}; - const auto roundedCornerState = getRoundedCornerState(); + const auto roundedCornerState = getRoundedCornerStateLocked(); const auto cropRect = roundedCornerState.cropRect; setupRoundedCornersCropCoordinates(win, cropRect); @@ -91,6 +92,7 @@ void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& trans } getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; + Mutex::Autolock lock(mStateMutex); half4 color = getColor(); error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), static_cast<uint8_t>(std::round(255.0f * color.g)), @@ -111,12 +113,12 @@ void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& trans } getBE().compositionInfo.hwc.transform = HWC2::Transform::None; - error = hwcLayer->setColorTransform(getColorTransform()); + error = hwcLayer->setColorTransform(getColorTransformLocked()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.colorTransform = getColorTransform(); + getBE().compositionInfo.hwc.colorTransform = getColorTransformLocked(); error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); if (error != HWC2::Error::None) { diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index d1b1697af8..5850a2e699 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -29,12 +29,12 @@ public: ~ColorLayer() override; virtual const char* getTypeId() const { return "ColorLayer"; } - virtual void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform); - bool isVisible() const override; + virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) + EXCLUDES(mStateMutex); + bool isVisible() const override EXCLUDES(mStateMutex); void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) override; + int32_t supportedPerFrameMetadata) override EXCLUDES(mStateMutex); bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; } diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index 413844b6f5..6c4f7c848d 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -31,7 +31,7 @@ public: const char* getTypeId() const override { return "ContainerLayer"; } void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) override; - bool isVisible() const override; + bool isVisible() const override EXCLUDES(mStateMutex); void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport, int32_t supportedPerFrameMetadata) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6d0fdad3d7..f4b3cddc63 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -83,35 +83,35 @@ Layer::Layer(const LayerCreationArgs& args) mTransactionName = String8("TX - ") + mName; - mCurrentState.active_legacy.w = args.w; - mCurrentState.active_legacy.h = args.h; - mCurrentState.flags = layerFlags; - mCurrentState.active_legacy.transform.set(0, 0); - mCurrentState.crop_legacy.makeInvalid(); - mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy; - mCurrentState.z = 0; - mCurrentState.color.a = 1.0f; - mCurrentState.layerStack = 0; - mCurrentState.sequence = 0; - mCurrentState.requested_legacy = mCurrentState.active_legacy; - mCurrentState.appId = 0; - mCurrentState.type = 0; - mCurrentState.active.w = UINT32_MAX; - mCurrentState.active.h = UINT32_MAX; - mCurrentState.active.transform.set(0, 0); - mCurrentState.transform = 0; - mCurrentState.transformToDisplayInverse = false; - mCurrentState.crop.makeInvalid(); - mCurrentState.acquireFence = new Fence(-1); - mCurrentState.dataspace = ui::Dataspace::UNKNOWN; - mCurrentState.hdrMetadata.validTypes = 0; - mCurrentState.surfaceDamageRegion.clear(); - mCurrentState.cornerRadius = 0.0f; - mCurrentState.api = -1; - mCurrentState.hasColorTransform = false; + mState.current.active_legacy.w = args.w; + mState.current.active_legacy.h = args.h; + mState.current.flags = layerFlags; + mState.current.active_legacy.transform.set(0, 0); + mState.current.crop_legacy.makeInvalid(); + mState.current.requestedCrop_legacy = mState.current.crop_legacy; + mState.current.z = 0; + mState.current.color.a = 1.0f; + mState.current.layerStack = 0; + mState.current.sequence = 0; + mState.current.requested_legacy = mState.current.active_legacy; + mState.current.appId = 0; + mState.current.type = 0; + mState.current.active.w = UINT32_MAX; + mState.current.active.h = UINT32_MAX; + mState.current.active.transform.set(0, 0); + mState.current.transform = 0; + mState.current.transformToDisplayInverse = false; + mState.current.crop.makeInvalid(); + mState.current.acquireFence = new Fence(-1); + mState.current.dataspace = ui::Dataspace::UNKNOWN; + mState.current.hdrMetadata.validTypes = 0; + mState.current.surfaceDamageRegion.clear(); + mState.current.cornerRadius = 0.0f; + mState.current.api = -1; + mState.current.hasColorTransform = false; // drawing state & current state are identical - mDrawingState = mCurrentState; + mState.drawing = mState.current; CompositorTiming compositorTiming; args.flinger->getCompositorTiming(&compositorTiming); @@ -148,14 +148,17 @@ void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} void Layer::onRemovedFromCurrentState() { mRemovedFromCurrentState = true; - // the layer is removed from SF mCurrentState to mLayersPendingRemoval - if (mCurrentState.zOrderRelativeOf != nullptr) { - sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote(); - if (strongRelative != nullptr) { - strongRelative->removeZOrderRelative(this); - mFlinger->setTransactionFlags(eTraversalNeeded); + { + Mutex::Autolock lock(mStateMutex); + // the layer is removed from SF mState.current to mLayersPendingRemoval + if (mState.current.zOrderRelativeOf != nullptr) { + sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote(); + if (strongRelative != nullptr) { + strongRelative->removeZOrderRelative(this); + mFlinger->setTransactionFlags(eTraversalNeeded); + } + mState.current.zOrderRelativeOf = nullptr; } - mCurrentState.zOrderRelativeOf = nullptr; } // Since we are no longer reachable from CurrentState SurfaceFlinger @@ -294,21 +297,32 @@ static FloatRect reduce(const FloatRect& win, const Region& exclude) { } Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { + Mutex::Autolock lock(mStateMutex); const State& s(getDrawingState()); Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region(); - FloatRect bounds = computeBounds(transparentRegion); - ui::Transform t = getTransform(); + FloatRect bounds = computeBoundsLocked(transparentRegion); + ui::Transform t = getTransformLocked(); // Transform to screen space. bounds = t.transform(bounds); return Rect{bounds}; } FloatRect Layer::computeBounds() const { + Mutex::Autolock lock(mStateMutex); + return computeBoundsLocked(); +} + +FloatRect Layer::computeBoundsLocked() const { const State& s(getDrawingState()); - return computeBounds(getActiveTransparentRegion(s)); + return computeBoundsLocked(getActiveTransparentRegion(s)); } FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { + Mutex::Autolock lock(mStateMutex); + return computeBoundsLocked(activeTransparentRegion); +} + +FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const { const State& s(getDrawingState()); Rect bounds = getCroppedBufferSize(s); FloatRect floatBounds = bounds.toFloatRect(); @@ -361,6 +375,7 @@ FloatRect Layer::cropChildBounds(const FloatRect& childBounds) const { // child bounds as well. ui::Transform t = s.active_legacy.transform; croppedBounds = t.transform(croppedBounds); + Mutex::Autolock lock(p->mStateMutex); croppedBounds = p->cropChildBounds(croppedBounds); croppedBounds = t.inverse().transform(croppedBounds); } @@ -388,8 +403,8 @@ Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const { // if there are no window scaling involved, this operation will map to full // pixels in the buffer. - FloatRect activeCropFloat = computeBounds(); - ui::Transform t = getTransform(); + FloatRect activeCropFloat = computeBoundsLocked(); + ui::Transform t = getTransformLocked(); // Transform to screen space. activeCropFloat = t.transform(activeCropFloat); activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect()); @@ -439,7 +454,7 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const { // which means using the inverse of the current transform set on the // SurfaceFlingerConsumer. uint32_t invTransform = mCurrentTransform; - if (getTransformToDisplayInverse()) { + if (getTransformToDisplayInverseLocked()) { /* * the code below applies the primary display's inverse transform to the * buffer @@ -490,6 +505,7 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const { } void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { + Mutex::Autolock lock(mStateMutex); const auto displayId = display->getId(); LOG_ALWAYS_FATAL_IF(!displayId); RETURN_IF_NO_HWC_LAYER(*displayId); @@ -498,7 +514,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { // enable this layer hwcInfo.forceClientComposition = false; - if (isSecure() && !display->isSecure()) { + if (isSecureLocked() && !display->isSecure()) { hwcInfo.forceClientComposition = true; } @@ -508,7 +524,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { const State& s(getDrawingState()); const Rect bufferSize = getBufferSize(s); auto blendMode = HWC2::BlendMode::None; - if (!isOpaque(s) || getAlpha() != 1.0f) { + if (!isOpaque(s) || getAlphaLocked() != 1.0f) { blendMode = mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage; } @@ -523,7 +539,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects Region activeTransparentRegion(getActiveTransparentRegion(s)); - ui::Transform t = getTransform(); + ui::Transform t = getTransformLocked(); Rect activeCrop = getCrop(s); if (!activeCrop.isEmpty() && bufferSize.isValid()) { activeCrop = t.transform(activeCrop); @@ -551,7 +567,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { // computeBounds returns a FloatRect to provide more accuracy during the // transformation. We then round upon constructing 'frame'. - Rect frame{t.transform(computeBounds(activeTransparentRegion))}; + Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))}; if (!frame.intersect(display->getViewport(), &frame)) { frame.clear(); } @@ -579,7 +595,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { } getBE().compositionInfo.hwc.sourceCrop = sourceCrop; - float alpha = static_cast<float>(getAlpha()); + float alpha = static_cast<float>(getAlphaLocked()); error = hwcLayer->setPlaneAlpha(alpha); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: " @@ -596,6 +612,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { int appId = s.appId; sp<Layer> parent = mDrawingParent.promote(); if (parent.get()) { + Mutex::Autolock lock(parent->mStateMutex); auto& parentState = parent->getDrawingState(); if (parentState.type >= 0 || parentState.appId >= 0) { type = parentState.type; @@ -621,7 +638,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { const ui::Transform bufferOrientation(mCurrentTransform); ui::Transform transform(tr * t * bufferOrientation); - if (getTransformToDisplayInverse()) { + if (getTransformToDisplayInverseLocked()) { /* * the code below applies the primary display's inverse transform to the * buffer @@ -671,6 +688,7 @@ bool Layer::getForceClientComposition(DisplayId displayId) { } void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) { + Mutex::Autolock lock(mStateMutex); const auto displayId = display->getId(); LOG_ALWAYS_FATAL_IF(!displayId); if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) { @@ -685,7 +703,7 @@ void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) { Rect win = getCroppedBufferSize(s); // Subtract the transparent region and snap to the bounds Rect bounds = reduce(win, getActiveTransparentRegion(s)); - Rect frame(getTransform().transform(bounds)); + Rect frame(getTransformLocked().transform(bounds)); frame.intersect(display->getViewport(), &frame); auto& displayTransform = display->getTransform(); auto position = displayTransform.transform(frame); @@ -715,6 +733,7 @@ void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) { void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue, float alpha) const { auto& engine(mFlinger->getRenderEngine()); + Mutex::Autolock lock(mStateMutex); computeGeometry(renderArea, getBE().mMesh, false); engine.setupFillWithColor(red, green, blue, alpha); engine.drawMesh(getBE().mMesh); @@ -799,14 +818,14 @@ void Layer::computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh, bool useIdentityTransform) const { const ui::Transform renderAreaTransform(renderArea.getTransform()); - FloatRect win = computeBounds(); + FloatRect win = computeBoundsLocked(); vec2 lt = vec2(win.left, win.top); vec2 lb = vec2(win.left, win.bottom); vec2 rb = vec2(win.right, win.bottom); vec2 rt = vec2(win.right, win.top); - ui::Transform layerTransform = getTransform(); + ui::Transform layerTransform = getTransformLocked(); if (!useIdentityTransform) { lt = layerTransform.transform(lt); lb = layerTransform.transform(lb); @@ -822,7 +841,12 @@ void Layer::computeGeometry(const RenderArea& renderArea, } bool Layer::isSecure() const { - const State& s(mDrawingState); + Mutex::Autolock lock(mStateMutex); + return isSecureLocked(); +} + +bool Layer::isSecureLocked() const { + const State& s(mState.drawing); return (s.flags & layer_state_t::eLayerSecure); } @@ -850,9 +874,13 @@ void Layer::clearVisibilityRegions() { // ---------------------------------------------------------------------------- // transaction // ---------------------------------------------------------------------------- - void Layer::pushPendingState() { - if (!mCurrentState.modified) { + Mutex::Autolock lock(mStateMutex); + pushPendingStateLocked(); +} + +void Layer::pushPendingStateLocked() { + if (!mState.current.modified) { return; } @@ -860,22 +888,22 @@ void Layer::pushPendingState() { // point and send it to the remote layer. // We don't allow installing sync points after we are removed from the current state // as we won't be able to signal our end. - if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) { - sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote(); + if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) { + sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote(); if (barrierLayer == nullptr) { ALOGE("[%s] Unable to promote barrier Layer.", mName.string()); // If we can't promote the layer we are intended to wait on, // then it is expired or otherwise invalid. Allow this transaction // to be applied as per normal (no synchronization). - mCurrentState.barrierLayer_legacy = nullptr; + mState.current.barrierLayer_legacy = nullptr; } else { - auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy); + auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy); if (barrierLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { // We already missed the frame we're supposed to synchronize // on, so go ahead and apply the state update - mCurrentState.barrierLayer_legacy = nullptr; + mState.current.barrierLayer_legacy = nullptr; } } @@ -883,21 +911,21 @@ void Layer::pushPendingState() { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } - mPendingStates.push_back(mCurrentState); - ATRACE_INT(mTransactionName.string(), mPendingStates.size()); + mState.pending.push_back(mState.current); + ATRACE_INT(mTransactionName.string(), mState.pending.size()); } void Layer::popPendingState(State* stateToCommit) { - *stateToCommit = mPendingStates[0]; + *stateToCommit = mState.pending[0]; - mPendingStates.removeAt(0); - ATRACE_INT(mTransactionName.string(), mPendingStates.size()); + mState.pending.removeAt(0); + ATRACE_INT(mTransactionName.string(), mState.pending.size()); } bool Layer::applyPendingStates(State* stateToCommit) { bool stateUpdateAvailable = false; - while (!mPendingStates.empty()) { - if (mPendingStates[0].barrierLayer_legacy != nullptr) { + while (!mState.pending.empty()) { + if (mState.pending[0].barrierLayer_legacy != nullptr) { if (mRemoteSyncPoints.empty()) { // If we don't have a sync point for this, apply it anyway. It // will be visually wrong, but it should keep us from getting @@ -909,7 +937,7 @@ bool Layer::applyPendingStates(State* stateToCommit) { } if (mRemoteSyncPoints.front()->getFrameNumber() != - mPendingStates[0].frameNumber_legacy) { + mState.pending[0].frameNumber_legacy) { ALOGE("[%s] Unexpected sync point frame number found", mName.string()); // Signal our end of the sync point and then dispose of it @@ -937,12 +965,12 @@ bool Layer::applyPendingStates(State* stateToCommit) { // If we still have pending updates, wake SurfaceFlinger back up and point // it at this layer so we can process them - if (!mPendingStates.empty()) { + if (!mState.pending.empty()) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } - mCurrentState.modified = false; + mState.current.modified = false; return stateUpdateAvailable; } @@ -1039,7 +1067,8 @@ uint32_t Layer::doTransaction(uint32_t flags) { return 0; } - pushPendingState(); + Mutex::Autolock lock(mStateMutex); + pushPendingStateLocked(); State c = getCurrentState(); if (!applyPendingStates(&c)) { return 0; @@ -1071,49 +1100,60 @@ uint32_t Layer::doTransaction(uint32_t flags) { clearSyncPoints(); } - if (mCurrentState.inputInfoChanged) { + if (mState.current.inputInfoChanged) { flags |= eInputInfoChanged; - mCurrentState.inputInfoChanged = false; + mState.current.inputInfoChanged = false; } // Commit the transaction commitTransaction(c); - mCurrentState.callbackHandles = {}; + mState.current.callbackHandles = {}; return flags; } void Layer::commitTransaction(const State& stateToCommit) { - mDrawingState = stateToCommit; + mState.drawing = stateToCommit; +} + +uint32_t Layer::getTransactionFlags() const { + Mutex::Autolock lock(mStateMutex); + return mState.transactionFlags; } uint32_t Layer::getTransactionFlags(uint32_t flags) { - return mTransactionFlags.fetch_and(~flags) & flags; + Mutex::Autolock lock(mStateMutex); + uint32_t and_flags = mState.transactionFlags & flags; + mState.transactionFlags &= ~flags; + return and_flags; } uint32_t Layer::setTransactionFlags(uint32_t flags) { - return mTransactionFlags.fetch_or(flags); + uint32_t old_flags = mState.transactionFlags; + mState.transactionFlags |= flags; + return old_flags; } bool Layer::setPosition(float x, float y, bool immediate) { - if (mCurrentState.requested_legacy.transform.tx() == x && - mCurrentState.requested_legacy.transform.ty() == y) + Mutex::Autolock lock(mStateMutex); + if (mState.current.requested_legacy.transform.tx() == x && + mState.current.requested_legacy.transform.ty() == y) return false; - mCurrentState.sequence++; + mState.current.sequence++; // We update the requested and active position simultaneously because // we want to apply the position portion of the transform matrix immediately, // but still delay scaling when resizing a SCALING_MODE_FREEZE layer. - mCurrentState.requested_legacy.transform.set(x, y); + mState.current.requested_legacy.transform.set(x, y); if (immediate && !mFreezeGeometryUpdates) { // Here we directly update the active state // unlike other setters, because we store it within // the transform, but use different latching rules. // b/38182305 - mCurrentState.active_legacy.transform.set(x, y); + mState.current.active_legacy.transform.set(x, y); } mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate; - mCurrentState.modified = true; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -1146,38 +1186,44 @@ bool Layer::setChildRelativeLayer(const sp<Layer>& childLayer, } bool Layer::setLayer(int32_t z) { - if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false; - mCurrentState.sequence++; - mCurrentState.z = z; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current)) + return false; + + mState.current.sequence++; + mState.current.z = z; + mState.current.modified = true; // Discard all relative layering. - if (mCurrentState.zOrderRelativeOf != nullptr) { - sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote(); + if (mState.current.zOrderRelativeOf != nullptr) { + sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote(); if (strongRelative != nullptr) { strongRelative->removeZOrderRelative(this); } - mCurrentState.zOrderRelativeOf = nullptr; + mState.current.zOrderRelativeOf = nullptr; } setTransactionFlags(eTransactionNeeded); return true; } void Layer::removeZOrderRelative(const wp<Layer>& relative) { - mCurrentState.zOrderRelatives.remove(relative); - mCurrentState.sequence++; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.zOrderRelatives.remove(relative); + mState.current.sequence++; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); } void Layer::addZOrderRelative(const wp<Layer>& relative) { - mCurrentState.zOrderRelatives.add(relative); - mCurrentState.modified = true; - mCurrentState.sequence++; + Mutex::Autolock lock(mStateMutex); + mState.current.zOrderRelatives.add(relative); + mState.current.modified = true; + mState.current.sequence++; setTransactionFlags(eTransactionNeeded); } bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) { + Mutex::Autolock lock(mStateMutex); sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get()); if (handle == nullptr) { return false; @@ -1187,20 +1233,20 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati return false; } - if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) && - mCurrentState.zOrderRelativeOf == relative) { + if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) && + mState.current.zOrderRelativeOf == relative) { return false; } - mCurrentState.sequence++; - mCurrentState.modified = true; - mCurrentState.z = relativeZ; + mState.current.sequence++; + mState.current.modified = true; + mState.current.z = relativeZ; - auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote(); + auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote(); if (oldZOrderRelativeOf != nullptr) { oldZOrderRelativeOf->removeZOrderRelative(this); } - mCurrentState.zOrderRelativeOf = relative; + mState.current.zOrderRelativeOf = relative; relative->addZOrderRelative(this); setTransactionFlags(eTransactionNeeded); @@ -1209,48 +1255,51 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati } bool Layer::setSize(uint32_t w, uint32_t h) { - if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h) + Mutex::Autolock lock(mStateMutex); + if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h) return false; - mCurrentState.requested_legacy.w = w; - mCurrentState.requested_legacy.h = h; - mCurrentState.modified = true; + mState.current.requested_legacy.w = w; + mState.current.requested_legacy.h = h; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); // record the new size, from this point on, when the client request // a buffer, it'll get the new size. - setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h); + setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h); return true; } bool Layer::setAlpha(float alpha) { - if (mCurrentState.color.a == alpha) return false; - mCurrentState.sequence++; - mCurrentState.color.a = alpha; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.color.a == alpha) return false; + mState.current.sequence++; + mState.current.color.a = alpha; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setColor(const half3& color) { - if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g && - color.b == mCurrentState.color.b) + Mutex::Autolock lock(mStateMutex); + if (color.r == mState.current.color.r && color.g == mState.current.color.g && + color.b == mState.current.color.b) return false; - mCurrentState.sequence++; - mCurrentState.color.r = color.r; - mCurrentState.color.g = color.g; - mCurrentState.color.b = color.b; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.color.r = color.r; + mState.current.color.g = color.g; + mState.current.color.b = color.b; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setCornerRadius(float cornerRadius) { - if (mCurrentState.cornerRadius == cornerRadius) - return false; + Mutex::Autolock lock(mStateMutex); + if (mState.current.cornerRadius == cornerRadius) return false; - mCurrentState.sequence++; - mCurrentState.cornerRadius = cornerRadius; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.cornerRadius = cornerRadius; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -1264,45 +1313,50 @@ bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored"); return false; } - mCurrentState.sequence++; - mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, - matrix.dsdy); - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.sequence++; + mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, + matrix.dsdy); + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setTransparentRegionHint(const Region& transparent) { - mCurrentState.requestedTransparentRegion_legacy = transparent; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.requestedTransparentRegion_legacy = transparent; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setFlags(uint8_t flags, uint8_t mask) { - const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); - if (mCurrentState.flags == newFlags) return false; - mCurrentState.sequence++; - mCurrentState.flags = newFlags; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask); + if (mState.current.flags == newFlags) return false; + mState.current.sequence++; + mState.current.flags = newFlags; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setCrop_legacy(const Rect& crop, bool immediate) { - if (mCurrentState.requestedCrop_legacy == crop) return false; - mCurrentState.sequence++; - mCurrentState.requestedCrop_legacy = crop; + Mutex::Autolock lock(mStateMutex); + if (mState.current.requestedCrop_legacy == crop) return false; + mState.current.sequence++; + mState.current.requestedCrop_legacy = crop; if (immediate && !mFreezeGeometryUpdates) { - mCurrentState.crop_legacy = crop; + mState.current.crop_legacy = crop; } mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate; - mCurrentState.modified = true; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool Layer::setOverrideScalingMode(int32_t scalingMode) { + Mutex::Autolock lock(mStateMutex); if (scalingMode == mOverrideScalingMode) return false; mOverrideScalingMode = scalingMode; setTransactionFlags(eTransactionNeeded); @@ -1310,22 +1364,29 @@ bool Layer::setOverrideScalingMode(int32_t scalingMode) { } void Layer::setInfo(int32_t type, int32_t appId) { - mCurrentState.appId = appId; - mCurrentState.type = type; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.appId = appId; + mState.current.type = type; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); } bool Layer::setLayerStack(uint32_t layerStack) { - if (mCurrentState.layerStack == layerStack) return false; - mCurrentState.sequence++; - mCurrentState.layerStack = layerStack; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.layerStack == layerStack) return false; + mState.current.sequence++; + mState.current.layerStack = layerStack; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } uint32_t Layer::getLayerStack() const { + Mutex::Autolock lock(mStateMutex); + return getLayerStackLocked(); +} + +uint32_t Layer::getLayerStackLocked() const { auto p = mDrawingParent.promote(); if (p == nullptr) { return getDrawingState().layerStack; @@ -1334,15 +1395,16 @@ uint32_t Layer::getLayerStack() const { } void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) { - mCurrentState.barrierLayer_legacy = barrierLayer; - mCurrentState.frameNumber_legacy = frameNumber; + Mutex::Autolock lock(mStateMutex); + mState.current.barrierLayer_legacy = barrierLayer; + mState.current.frameNumber_legacy = frameNumber; // We don't set eTransactionNeeded, because just receiving a deferral // request without any other state updates shouldn't actually induce a delay - mCurrentState.modified = true; - pushPendingState(); - mCurrentState.barrierLayer_legacy = nullptr; - mCurrentState.frameNumber_legacy = 0; - mCurrentState.modified = false; + mState.current.modified = true; + pushPendingStateLocked(); + mState.current.barrierLayer_legacy = nullptr; + mState.current.frameNumber_legacy = 0; + mState.current.modified = false; } void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) { @@ -1355,7 +1417,8 @@ void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint6 // ---------------------------------------------------------------------------- bool Layer::isHiddenByPolicy() const { - const State& s(mDrawingState); + Mutex::Autolock lock(mStateMutex); + const State& s(mState.drawing); const auto& parent = mDrawingParent.promote(); if (parent != nullptr && parent->isHiddenByPolicy()) { return true; @@ -1400,6 +1463,7 @@ void Layer::updateTransformHint(const sp<const DisplayDevice>& display) const { // TODO(marissaw): add new layer state info to layer debugging LayerDebugInfo Layer::getLayerDebugInfo() const { + Mutex::Autolock lock(mStateMutex); LayerDebugInfo info; const State& ds = getDrawingState(); info.mName = getName(); @@ -1409,7 +1473,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mTransparentRegion = ds.activeTransparentRegion_legacy; info.mVisibleRegion = visibleRegion; info.mSurfaceDamageRegion = surfaceDamageRegion; - info.mLayerStack = getLayerStack(); + info.mLayerStack = getLayerStackLocked(); info.mX = ds.active_legacy.transform.tx(); info.mY = ds.active_legacy.transform.ty(); info.mZ = ds.z; @@ -1445,6 +1509,13 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { return info; } +std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) { + Mutex::Autolock lock(mStateMutex); + const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing; + + return {state.layerStack, state.z}; +} + void Layer::miniDumpHeader(std::string& result) { result.append("-------------------------------"); result.append("-------------------------------"); @@ -1461,6 +1532,7 @@ void Layer::miniDumpHeader(std::string& result) { } void Layer::miniDump(std::string& result, DisplayId displayId) const { + Mutex::Autolock lock(mStateMutex); if (!hasHwcLayer(displayId)) { return; } @@ -1589,6 +1661,7 @@ bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { } if (attachChildren()) { + Mutex::Autolock lock(mStateMutex); setTransactionFlags(eTransactionNeeded); } for (const sp<Layer>& child : mCurrentChildren) { @@ -1639,6 +1712,7 @@ bool Layer::reparent(const sp<IBinder>& newParentHandle) { client->updateParent(newParent); } + Mutex::Autolock lock(mStateMutex); if (mLayerDetached) { mLayerDetached = false; setTransactionFlags(eTransactionNeeded); @@ -1682,18 +1756,24 @@ bool Layer::attachChildren() { bool Layer::setColorTransform(const mat4& matrix) { static const mat4 identityMatrix = mat4(); - if (mCurrentState.colorTransform == matrix) { + Mutex::Autolock lock(mStateMutex); + if (mState.current.colorTransform == matrix) { return false; } - ++mCurrentState.sequence; - mCurrentState.colorTransform = matrix; - mCurrentState.hasColorTransform = matrix != identityMatrix; - mCurrentState.modified = true; + ++mState.current.sequence; + mState.current.colorTransform = matrix; + mState.current.hasColorTransform = matrix != identityMatrix; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } mat4 Layer::getColorTransform() const { + Mutex::Autolock lock(mStateMutex); + return getColorTransformLocked(); +} + +mat4 Layer::getColorTransformLocked() const { mat4 colorTransform = mat4(getDrawingState().colorTransform); if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) { colorTransform = parent->getColorTransform() * colorTransform; @@ -1702,6 +1782,7 @@ mat4 Layer::getColorTransform() const { } bool Layer::hasColorTransform() const { + Mutex::Autolock lock(mStateMutex); bool hasColorTransform = getDrawingState().hasColorTransform; if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) { hasColorTransform = hasColorTransform || parent->hasColorTransform(); @@ -1732,12 +1813,18 @@ void Layer::clearSyncPoints() { } int32_t Layer::getZ() const { - return mDrawingState.z; + Mutex::Autolock lock(mStateMutex); + return mState.drawing.z; } bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) { + Mutex::Autolock lock(mStateMutex); + return usingRelativeZLocked(stateSet); +} + +bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) { const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; - const State& state = useDrawing ? mDrawingState : mCurrentState; + const State& state = useDrawing ? mState.drawing : mState.current; return state.zOrderRelativeOf != nullptr; } @@ -1747,7 +1834,7 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak "makeTraversalList received invalid stateSet"); const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; - const State& state = useDrawing ? mDrawingState : mCurrentState; + const State& state = useDrawing ? mState.drawing : mState.current; if (state.zOrderRelatives.size() == 0) { *outSkipRelativeZUsers = true; @@ -1763,7 +1850,7 @@ __attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::mak } for (const sp<Layer>& child : children) { - const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState; + const State& childState = useDrawing ? child->mState.drawing : child->mState.current; if (childState.zOrderRelativeOf != nullptr) { continue; } @@ -1802,7 +1889,6 @@ void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector:: visitor(this); for (; i < list.size(); i++) { const auto& relative = list[i]; - if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) { continue; } @@ -1850,7 +1936,7 @@ LayerVector Layer::makeChildrenTraversalList(LayerVector::StateSet stateSet, "makeTraversalList received invalid stateSet"); const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; - const State& state = useDrawing ? mDrawingState : mCurrentState; + const State& state = useDrawing ? mState.drawing : mState.current; LayerVector traverse(stateSet); for (const wp<Layer>& weakRelative : state.zOrderRelatives) { @@ -1863,7 +1949,7 @@ LayerVector Layer::makeChildrenTraversalList(LayerVector::StateSet stateSet, } for (const sp<Layer>& child : children) { - const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState; + const State& childState = useDrawing ? child->mState.drawing : child->mState.current; // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a // descendent of the top most parent of the tree. If it's not a descendent, then just add // the child here since it won't be added later as a relative. @@ -1920,10 +2006,16 @@ void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet, } ui::Transform Layer::getTransform() const { + Mutex::Autolock lock(mStateMutex); + return getTransformLocked(); +} + +ui::Transform Layer::getTransformLocked() const { ui::Transform t; const auto& p = mDrawingParent.promote(); if (p != nullptr) { - t = p->getTransform(); + Mutex::Autolock lock(p->mStateMutex); + t = p->getTransformLocked(); // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g. // it isFixedSize) then there may be additional scaling not accounted @@ -1951,18 +2043,27 @@ ui::Transform Layer::getTransform() const { } half Layer::getAlpha() const { - const auto& p = mDrawingParent.promote(); + Mutex::Autolock lock(mStateMutex); + return getAlphaLocked(); +} +half Layer::getAlphaLocked() const { + const auto& p = mDrawingParent.promote(); half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf; return parentAlpha * getDrawingState().color.a; } half4 Layer::getColor() const { const half4 color(getDrawingState().color); - return half4(color.r, color.g, color.b, getAlpha()); + return half4(color.r, color.g, color.b, getAlphaLocked()); } Layer::RoundedCornerState Layer::getRoundedCornerState() const { + Mutex::Autolock lock(mStateMutex); + return getRoundedCornerStateLocked(); +} + +Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const { const auto& p = mDrawingParent.promote(); if (p != nullptr) { RoundedCornerState parentState = p->getRoundedCornerState(); @@ -1979,7 +2080,7 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { } } const float radius = getDrawingState().cornerRadius; - return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState(); + return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState(); } void Layer::commitChildList() { @@ -1992,19 +2093,21 @@ void Layer::commitChildList() { } void Layer::setInputInfo(const InputWindowInfo& info) { - mCurrentState.inputInfo = info; - mCurrentState.modified = true; - mCurrentState.inputInfoChanged = true; + Mutex::Autolock lock(mStateMutex); + mState.current.inputInfo = info; + mState.current.modified = true; + mState.current.inputInfoChanged = true; setTransactionFlags(eTransactionNeeded); } void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) { + Mutex::Autolock lock(mStateMutex); const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren; - const State& state = useDrawing ? mDrawingState : mCurrentState; + const State& state = useDrawing ? mState.drawing : mState.current; ui::Transform requestedTransform = state.active_legacy.transform; - ui::Transform transform = getTransform(); + ui::Transform transform = getTransformLocked(); layerInfo->set_id(sequence); layerInfo->set_name(getName().c_str()); @@ -2026,7 +2129,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region()); LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region()); - layerInfo->set_layer_stack(getLayerStack()); + layerInfo->set_layer_stack(getLayerStackLocked()); layerInfo->set_z(state.z); PositionProto* position = layerInfo->mutable_position(); @@ -2042,7 +2145,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) size->set_h(state.active_legacy.h); LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop()); - layerInfo->set_corner_radius(getRoundedCornerState().radius); + layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius); layerInfo->set_is_opaque(isOpaque(state)); layerInfo->set_invalidate(contentDirty); @@ -2083,7 +2186,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_curr_frame(mCurrentFrameNumber); layerInfo->set_effective_scaling_mode(getEffectiveScalingMode()); - for (const auto& pendingState : mPendingStates) { + for (const auto& pendingState : mState.pending) { auto barrierLayer = pendingState.barrierLayer_legacy.promote(); if (barrierLayer != nullptr) { BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer(); @@ -2127,19 +2230,25 @@ bool Layer::isRemovedFromCurrentState() const { } InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) { - InputWindowInfo info = mDrawingState.inputInfo; + InputWindowInfo info; + ui::Transform t; + Rect layerBounds; + { + Mutex::Autolock lock(mStateMutex); + info = mState.drawing.inputInfo; + t = getTransformLocked(); + const float xScale = t.sx(); + const float yScale = t.sy(); + if (xScale != 1.0f || yScale != 1.0f) { + info.windowXScale *= 1.0f / xScale; + info.windowYScale *= 1.0f / yScale; + info.touchableRegion.scaleSelf(xScale, yScale); + } - ui::Transform t = getTransform(); - const float xScale = t.sx(); - const float yScale = t.sy(); - if (xScale != 1.0f || yScale != 1.0f) { - info.windowXScale *= 1.0f / xScale; - info.windowYScale *= 1.0f / yScale; - info.touchableRegion.scaleSelf(xScale, yScale); + // Transform layer size to screen space and inset it by surface insets. + layerBounds = getCroppedBufferSize(getDrawingState()); } - // Transform layer size to screen space and inset it by surface insets. - Rect layerBounds = getCroppedBufferSize(getDrawingState()); layerBounds = t.transform(layerBounds); layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset); @@ -2162,7 +2271,8 @@ InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) { } bool Layer::hasInput() const { - return mDrawingState.inputInfo.token != nullptr; + Mutex::Autolock lock(mStateMutex); + return mState.drawing.inputInfo.token != nullptr; } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7b6709e20b..57ef65a18f 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -55,6 +55,7 @@ #include "RenderArea.h" using namespace android::surfaceflinger; +using StateSet = android::LayerVector::StateSet; namespace android { @@ -239,7 +240,7 @@ public: // also the rendered size of the layer prior to any transformations. Parent // or local matrix transformations will not affect the size of the buffer, // but may affect it's on-screen size or clipping. - virtual bool setSize(uint32_t w, uint32_t h); + virtual bool setSize(uint32_t w, uint32_t h) EXCLUDES(mStateMutex); // Set a 2x2 transformation matrix on the layer. This transform // will be applied after parent transforms, but before any final // producer specified transform. @@ -254,58 +255,76 @@ public: // setPosition operates in parent buffer space (pre parent-transform) or display // space for top-level layers. - virtual bool setPosition(float x, float y, bool immediate); + virtual bool setPosition(float x, float y, bool immediate) EXCLUDES(mStateMutex); // Buffer space - virtual bool setCrop_legacy(const Rect& crop, bool immediate); + virtual bool setCrop_legacy(const Rect& crop, bool immediate) EXCLUDES(mStateMutex); // TODO(b/38182121): Could we eliminate the various latching modes by // using the layer hierarchy? // ----------------------------------------------------------------------- - virtual bool setLayer(int32_t z); - virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ); + virtual bool setLayer(int32_t z) EXCLUDES(mStateMutex); + virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) + EXCLUDES(mStateMutex); - virtual bool setAlpha(float alpha); - virtual bool setColor(const half3& color); + virtual bool setAlpha(float alpha) EXCLUDES(mStateMutex); + virtual bool setColor(const half3& color) EXCLUDES(mStateMutex); // Set rounded corner radius for this layer and its children. // // We only support 1 radius per layer in the hierarchy, where parent layers have precedence. // The shape of the rounded corner rectangle is specified by the crop rectangle of the layer // from which we inferred the rounded corner radius. - virtual bool setCornerRadius(float cornerRadius); - virtual bool setTransparentRegionHint(const Region& transparent); - virtual bool setFlags(uint8_t flags, uint8_t mask); - virtual bool setLayerStack(uint32_t layerStack); - virtual uint32_t getLayerStack() const; + virtual bool setCornerRadius(float cornerRadius) EXCLUDES(mStateMutex); + virtual bool setTransparentRegionHint(const Region& transparent) EXCLUDES(mStateMutex); + virtual bool setFlags(uint8_t flags, uint8_t mask) EXCLUDES(mStateMutex); + virtual bool setLayerStack(uint32_t layerStack) EXCLUDES(mStateMutex); + virtual uint32_t getLayerStack() const EXCLUDES(mStateMutex); virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber); - virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber); - virtual bool setOverrideScalingMode(int32_t overrideScalingMode); - virtual void setInfo(int32_t type, int32_t appId); - virtual bool reparentChildren(const sp<IBinder>& layer); + virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) + EXCLUDES(mStateMutex); + virtual bool setOverrideScalingMode(int32_t overrideScalingMode) EXCLUDES(mStateMutex); + virtual void setInfo(int32_t type, int32_t appId) EXCLUDES(mStateMutex); + virtual bool reparentChildren(const sp<IBinder>& layer) EXCLUDES(mStateMutex); virtual void setChildrenDrawingParent(const sp<Layer>& layer); - virtual bool reparent(const sp<IBinder>& newParentHandle); + virtual bool reparent(const sp<IBinder>& newParentHandle) EXCLUDES(mStateMutex); virtual bool detachChildren(); bool attachChildren(); bool isLayerDetached() const { return mLayerDetached; } - virtual bool setColorTransform(const mat4& matrix); - virtual mat4 getColorTransform() const; - virtual bool hasColorTransform() const; + virtual bool setColorTransform(const mat4& matrix) EXCLUDES(mStateMutex); + mat4 getColorTransform() const EXCLUDES(mStateMutex); + virtual mat4 getColorTransformLocked() const REQUIRES(mStateMutex); + virtual bool hasColorTransform() const EXCLUDES(mStateMutex); + ; // Used only to set BufferStateLayer state - virtual bool setTransform(uint32_t /*transform*/) { return false; }; - virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; - virtual bool setCrop(const Rect& /*crop*/) { return false; }; - virtual bool setFrame(const Rect& /*frame*/) { return false; }; - virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) { return false; }; - virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; }; - virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; }; - virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; }; - virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; }; - virtual bool setApi(int32_t /*api*/) { return false; }; - virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; }; + virtual bool setTransform(uint32_t /*transform*/) EXCLUDES(mStateMutex) { return false; }; + virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) + EXCLUDES(mStateMutex) { + return false; + }; + virtual bool setCrop(const Rect& /*crop*/) EXCLUDES(mStateMutex) { return false; }; + virtual bool setFrame(const Rect& /*frame*/) EXCLUDES(mStateMutex) { return false; }; + virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) EXCLUDES(mStateMutex) { + return false; + }; + virtual bool setAcquireFence(const sp<Fence>& /*fence*/) EXCLUDES(mStateMutex) { + return false; + }; + virtual bool setDataspace(ui::Dataspace /*dataspace*/) EXCLUDES(mStateMutex) { return false; }; + virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) EXCLUDES(mStateMutex) { + return false; + }; + virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) EXCLUDES(mStateMutex) { + return false; + }; + virtual bool setApi(int32_t /*api*/) EXCLUDES(mStateMutex) { return false; }; + virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) + EXCLUDES(mStateMutex) { + return false; + }; virtual bool setTransactionCompletedListeners( - const std::vector<sp<CallbackHandle>>& /*handles*/) { + const std::vector<sp<CallbackHandle>>& /*handles*/) EXCLUDES(mStateMutex) { return false; }; @@ -324,18 +343,21 @@ public: virtual void useSurfaceDamage() {} virtual void useEmptyDamage() {} - uint32_t getTransactionFlags() const { return mTransactionFlags; } - uint32_t getTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); + uint32_t getTransactionFlags() const EXCLUDES(mStateMutex); + uint32_t getTransactionFlags(uint32_t flags) EXCLUDES(mStateMutex); + uint32_t setTransactionFlags(uint32_t flags) REQUIRES(mStateMutex); - bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const { + bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const EXCLUDES(mStateMutex) { return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay); } void computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh, - bool useIdentityTransform) const; - FloatRect computeBounds(const Region& activeTransparentRegion) const; - FloatRect computeBounds() const; + bool useIdentityTransform) const REQUIRES(mStateMutex); + FloatRect computeBounds(const Region& activeTransparentRegion) const EXCLUDES(mStateMutex); + FloatRect computeBoundsLocked(const Region& activeTransparentRegion) const + REQUIRES(mStateMutex); + FloatRect computeBounds() const EXCLUDES(mStateMutex); + FloatRect computeBoundsLocked() const REQUIRES(mStateMutex); int32_t getSequence() const { return sequence; } @@ -352,16 +374,21 @@ public: */ virtual bool isOpaque(const Layer::State&) const { return false; } + virtual bool isDrawingOpaque() const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return isOpaque(mState.drawing); + } + /* * isSecure - true if this surface is secure, that is if it prevents * screenshots or VNC servers. */ - bool isSecure() const; + bool isSecure() const EXCLUDES(mStateMutex); /* * isVisible - true if this layer is visible, false otherwise */ - virtual bool isVisible() const = 0; + virtual bool isVisible() const EXCLUDES(mStateMutex) = 0; /* * isHiddenByPolicy - true if this layer has been forced invisible. @@ -369,7 +396,7 @@ public: * For example if this layer has no active buffer, it may not be hidden by * policy, but it still can not be visible. */ - bool isHiddenByPolicy() const; + bool isHiddenByPolicy() const EXCLUDES(mStateMutex); /* * isFixedSize - true if content has a fixed size @@ -384,7 +411,8 @@ public: bool isRemovedFromCurrentState() const; void writeToProto(LayerProto* layerInfo, - LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing); + LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing) + EXCLUDES(mStateMutex); void writeToProto(LayerProto* layerInfo, DisplayId displayId); @@ -397,25 +425,32 @@ public: virtual Region getActiveTransparentRegion(const Layer::State& s) const { return s.activeTransparentRegion_legacy; } + + virtual Region getDrawingActiveTransparentRegion() const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return getActiveTransparentRegion(mState.drawing); + } + virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } protected: /* * onDraw - draws the surface. */ - virtual void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) = 0; + virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) + EXCLUDES(mStateMutex) = 0; public: virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {} virtual bool isHdrY410() const { return false; } - void setGeometry(const sp<const DisplayDevice>& display, uint32_t z); + void setGeometry(const sp<const DisplayDevice>& display, uint32_t z) EXCLUDES(mStateMutex); void forceClientComposition(DisplayId displayId); bool getForceClientComposition(DisplayId displayId); virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) = 0; + const Rect& viewport, int32_t supportedPerFrameMetadata) + EXCLUDES(mStateMutex) = 0; // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state @@ -423,7 +458,7 @@ public: HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const; void setClearClientTarget(DisplayId displayId, bool clear); bool getClearClientTarget(DisplayId displayId) const; - void updateCursorPosition(const sp<const DisplayDevice>& display); + void updateCursorPosition(const sp<const DisplayDevice>& display) EXCLUDES(mStateMutex); /* * called after page-flip @@ -446,7 +481,8 @@ public: virtual bool onPostComposition(const std::optional<DisplayId>& /*displayId*/, const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, - const CompositorTiming& /*compositorTiming*/) { + const CompositorTiming& /*compositorTiming*/) + EXCLUDES(mStateMutex) { return false; } @@ -458,14 +494,14 @@ public: * draw - performs some global clipping optimizations * and calls onDraw(). */ - void draw(const RenderArea& renderArea, const Region& clip); - void draw(const RenderArea& renderArea, bool useIdentityTransform); + void draw(const RenderArea& renderArea, const Region& clip) EXCLUDES(mStateMutex); + void draw(const RenderArea& renderArea, bool useIdentityTransform) EXCLUDES(mStateMutex); /* * doTransaction - process the transaction. This is a good place to figure * out which attributes of the surface have changed. */ - uint32_t doTransaction(uint32_t transactionFlags); + uint32_t doTransaction(uint32_t transactionFlags) EXCLUDES(mStateMutex); /* * setVisibleRegion - called to set the new visible region. This gives @@ -498,17 +534,17 @@ public: * to figure out if the content or size of a surface has changed. */ virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/, - const sp<Fence>& /*releaseFence*/) { + const sp<Fence>& /*releaseFence*/) EXCLUDES(mStateMutex) { return {}; } virtual bool isBufferLatched() const { return false; } /* - * called with the state lock from a binder thread when the layer is + * called with SurfaceFlinger mStateLock a binder thread when the layer is * removed from the current list to the pending removal list */ - void onRemovedFromCurrentState(); + void onRemovedFromCurrentState() EXCLUDES(mStateMutex); /* * Called when the layer is added back to the current state list. @@ -528,7 +564,7 @@ public: /* * Returns if a frame is ready */ - virtual bool hasReadyFrame() const { return false; } + virtual bool hasReadyFrame() const EXCLUDES(mStateMutex) { return false; } virtual int32_t getQueuedFrameCount() const { return 0; } @@ -557,17 +593,32 @@ public: } // ----------------------------------------------------------------------- - void clearWithOpenGL(const RenderArea& renderArea) const; + void clearWithOpenGL(const RenderArea& renderArea) const EXCLUDES(mStateMutex); + + inline const State& getDrawingState() const REQUIRES(mStateMutex) { return mState.drawing; } + + inline const State& getCurrentState() const REQUIRES(mStateMutex) { return mState.current; } + + inline State& getCurrentState() REQUIRES(mStateMutex) { return mState.current; } - inline const State& getDrawingState() const { return mDrawingState; } - inline const State& getCurrentState() const { return mCurrentState; } - inline State& getCurrentState() { return mCurrentState; } + std::tuple<uint32_t, int32_t> getLayerStackAndZ(StateSet stateSet) EXCLUDES(mStateMutex); + wp<Layer> getZOrderRelativeOf(StateSet stateSet) EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing; + + return state.zOrderRelativeOf; + } + + uint8_t getCurrentFlags() EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return mState.current.flags; + } - LayerDebugInfo getLayerDebugInfo() const; + LayerDebugInfo getLayerDebugInfo() const EXCLUDES(mStateMutex); /* always call base class first */ static void miniDumpHeader(std::string& result); - void miniDump(std::string& result, DisplayId displayId) const; + void miniDump(std::string& result, DisplayId displayId) const EXCLUDES(mStateMutex); void dumpFrameStats(std::string& result) const; void dumpFrameEvents(std::string& result); void clearFrameStats(); @@ -582,22 +633,29 @@ public: void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, FrameEventHistoryDelta* outDelta); - virtual bool getTransformToDisplayInverse() const { return false; } + bool getTransformToDisplayInverse() const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + return getTransformToDisplayInverseLocked(); + } + + virtual bool getTransformToDisplayInverseLocked() const REQUIRES(mStateMutex) { return false; } - ui::Transform getTransform() const; + ui::Transform getTransform() const EXCLUDES(mStateMutex); + ui::Transform getTransformLocked() const REQUIRES(mStateMutex); // Returns the Alpha of the Surface, accounting for the Alpha // of parent Surfaces in the hierarchy (alpha's will be multiplied // down the hierarchy). - half getAlpha() const; - half4 getColor() const; + half getAlpha() const EXCLUDES(mStateMutex); + half4 getColor() const REQUIRES(mStateMutex); // Returns how rounded corners should be drawn for this layer. // This will traverse the hierarchy until it reaches its root, finding topmost rounded // corner definition and converting it into current layer's coordinates. // As of now, only 1 corner radius per display list is supported. Subsequent ones will be // ignored. - RoundedCornerState getRoundedCornerState() const; + RoundedCornerState getRoundedCornerState() const EXCLUDES(mStateMutex); + RoundedCornerState getRoundedCornerStateLocked() const REQUIRES(mStateMutex); void traverseInReverseZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor); @@ -617,7 +675,7 @@ public: ssize_t removeChild(const sp<Layer>& layer); sp<Layer> getParent() const { return mCurrentParent.promote(); } bool hasParent() const { return getParent() != nullptr; } - Rect computeScreenBounds(bool reduceTransparentRegion = true) const; + Rect computeScreenBounds(bool reduceTransparentRegion = true) const EXCLUDES(mStateMutex); bool setChildLayer(const sp<Layer>& childLayer, int32_t z); bool setChildRelativeLayer(const sp<Layer>& childLayer, const sp<IBinder>& relativeToHandle, int32_t relativeZ); @@ -625,14 +683,23 @@ public: // Copy the current list of children to the drawing state. Called by // SurfaceFlinger to complete a transaction. void commitChildList(); - int32_t getZ() const; - virtual void pushPendingState(); + int32_t getZ() const EXCLUDES(mStateMutex); + void pushPendingState() EXCLUDES(mStateMutex); + virtual void pushPendingStateLocked() REQUIRES(mStateMutex); /** * Returns active buffer size in the correct orientation. Buffer size is determined by undoing * any buffer transformations. If the layer has no buffer then return INVALID_RECT. */ - virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; } + virtual Rect getBufferSize(const Layer::State&) const REQUIRES(mStateMutex) { + return Rect::INVALID_RECT; + } + + virtual Rect getBufferSize(StateSet stateSet) const EXCLUDES(mStateMutex) { + Mutex::Autolock lock(mStateMutex); + const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing; + return getBufferSize(state); + } protected: // constant @@ -661,16 +728,17 @@ protected: // For unit tests friend class TestableSurfaceFlinger; - void commitTransaction(const State& stateToCommit); + void commitTransaction(const State& stateToCommit) REQUIRES(mStateMutex); uint32_t getEffectiveUsage(uint32_t usage) const; - virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const; + virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const + REQUIRES(mStateMutex); // Compute the initial crop as specified by parent layers and the // SurfaceControl for this layer. Does not include buffer crop from the // IGraphicBufferProducer client, as that should not affect child clipping. // Returns in screen space. - Rect computeInitialCrop(const sp<const DisplayDevice>& display) const; + Rect computeInitialCrop(const sp<const DisplayDevice>& display) const REQUIRES(mStateMutex); /** * Setup rounded corners coordinates of this layer, taking into account the layer bounds and * crop coordinates, transforming them into layer space. @@ -678,13 +746,13 @@ protected: void setupRoundedCornersCropCoordinates(Rect win, const FloatRect& roundedCornersCrop) const; // drawing - void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, - float alpha) const; + void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, float alpha) const + EXCLUDES(mStateMutex); void setParent(const sp<Layer>& layer); LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers); - void addZOrderRelative(const wp<Layer>& relative); - void removeZOrderRelative(const wp<Layer>& relative); + void addZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex); + void removeZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex); class SyncPoint { public: @@ -720,9 +788,10 @@ protected: // Returns false if the relevant frame has already been latched bool addSyncPoint(const std::shared_ptr<SyncPoint>& point); - void popPendingState(State* stateToCommit); - virtual bool applyPendingStates(State* stateToCommit); - virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit); + void popPendingState(State* stateToCommit) REQUIRES(mStateMutex); + virtual bool applyPendingStates(State* stateToCommit) REQUIRES(mStateMutex); + virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit) + REQUIRES(mStateMutex); void clearSyncPoints(); @@ -755,14 +824,15 @@ public: bool getPremultipledAlpha() const; bool mPendingHWCDestroy{false}; - void setInputInfo(const InputWindowInfo& info); + void setInputInfo(const InputWindowInfo& info) EXCLUDES(mStateMutex); - InputWindowInfo fillInputInfo(const Rect& screenBounds); - bool hasInput() const; + InputWindowInfo fillInputInfo(const Rect& screenBounds) EXCLUDES(mStateMutex); + bool hasInput() const EXCLUDES(mStateMutex); protected: // ----------------------------------------------------------------------- - bool usingRelativeZ(LayerVector::StateSet stateSet); + bool usingRelativeZ(LayerVector::StateSet stateSet) EXCLUDES(mStateMutex); + bool usingRelativeZLocked(LayerVector::StateSet stateSet) REQUIRES(mStateMutex); bool mPremultipliedAlpha{true}; String8 mName; @@ -770,14 +840,14 @@ protected: bool mPrimaryDisplayOnly = false; - // these are protected by an external lock - State mCurrentState; - State mDrawingState; - std::atomic<uint32_t> mTransactionFlags{0}; - // Accessed from main thread and binder threads - Mutex mPendingStateMutex; - Vector<State> mPendingStates; + mutable Mutex mStateMutex; + struct { + State current; + State drawing; + uint32_t transactionFlags{0}; + Vector<State> pending; + } mState GUARDED_BY(mStateMutex); // Timestamp history for UIAutomation. Thread safe. FrameTracker mFrameTracker; @@ -850,7 +920,7 @@ private: * The cropped bounds must be transformed back from parent layer space to child layer space by * applying the inverse of the child's transformation. */ - FloatRect cropChildBounds(const FloatRect& childBounds) const; + FloatRect cropChildBounds(const FloatRect& childBounds) const REQUIRES(mStateMutex); /** * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return @@ -858,7 +928,12 @@ private: * A layer with an invalid buffer size and no crop is considered to be boundless. The layer * bounds are constrained by its parent bounds. */ - Rect getCroppedBufferSize(const Layer::State& s) const; + Rect getCroppedBufferSize(const Layer::State& s) const REQUIRES(mStateMutex); + + // locked version of public methods + bool isSecureLocked() const REQUIRES(mStateMutex); + virtual uint32_t getLayerStackLocked() const REQUIRES(mStateMutex); + half getAlphaLocked() const REQUIRES(mStateMutex); }; } // namespace android diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp index 84945247a6..a7db23ed4e 100644 --- a/services/surfaceflinger/LayerVector.cpp +++ b/services/surfaceflinger/LayerVector.cpp @@ -38,18 +38,12 @@ int LayerVector::do_compare(const void* lhs, const void* rhs) const const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs); const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs); - const auto& lState = - (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState(); - const auto& rState = - (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState(); + const auto& [ls, lz] = l->getLayerStackAndZ(mStateSet); + const auto& [rs, rz] = r->getLayerStackAndZ(mStateSet); - uint32_t ls = lState.layerStack; - uint32_t rs = rState.layerStack; if (ls != rs) return (ls > rs) ? 1 : -1; - int32_t lz = lState.z; - int32_t rz = rState.z; if (lz != rz) return (lz > rz) ? 1 : -1; @@ -62,9 +56,8 @@ int LayerVector::do_compare(const void* lhs, const void* rhs) const void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const { for (size_t i = 0; i < size(); i++) { const auto& layer = (*this)[i]; - auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState() - : layer->getDrawingState(); - if (state.zOrderRelativeOf != nullptr) { + auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet); + if (zOrderRelativeOf != nullptr) { continue; } layer->traverseInZOrder(stateSet, visitor); @@ -74,9 +67,8 @@ void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) co void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const { for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) { const auto& layer = (*this)[i]; - auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState() - : layer->getDrawingState(); - if (state.zOrderRelativeOf != nullptr) { + auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet); + if (zOrderRelativeOf != nullptr) { continue; } layer->traverseInReverseZOrder(stateSet, visitor); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a14ca2d2a2..178317caca 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2832,9 +2832,6 @@ void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displa outDirtyRegion.clear(); mDrawingState.traverseInReverseZOrder([&](Layer* layer) { - // start with the whole surface at its current location - const Layer::State& s(layer->getDrawingState()); - // only consider the layers on the given layer stack if (!layer->belongsToDisplay(display->getLayerStack(), display->isPrimary())) { return; @@ -2872,7 +2869,7 @@ void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displa // handle hidden surfaces by setting the visible region to empty if (CC_LIKELY(layer->isVisible())) { - const bool translucent = !layer->isOpaque(s); + const bool translucent = !layer->isDrawingOpaque(); Rect bounds(layer->computeScreenBounds()); visibleRegion.set(bounds); @@ -2882,7 +2879,8 @@ void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displa if (translucent) { if (tr.preserveRects()) { // transform the transparent region - transparentRegion = tr.transform(layer->getActiveTransparentRegion(s)); + transparentRegion = + tr.transform(layer->getDrawingActiveTransparentRegion()); } else { // transformation too complex, can't do the // transparent region optimization. @@ -3170,9 +3168,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& display) { case HWC2::Composition::Sideband: case HWC2::Composition::SolidColor: { LOG_ALWAYS_FATAL_IF(!displayId); - const Layer::State& state(layer->getDrawingState()); if (layer->getClearClientTarget(*displayId) && !firstLayer && - layer->isOpaque(state) && (layer->getAlpha() == 1.0f) && + layer->isDrawingOpaque() && (layer->getAlpha() == 1.0f) && layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) { // never clear the very first layer since we're // guaranteed the FB is already cleared @@ -5203,15 +5200,12 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, mFlinger(flinger), mChildrenOnly(childrenOnly) {} const ui::Transform& getTransform() const override { return mTransform; } - Rect getBounds() const override { - const Layer::State& layerState(mLayer->getDrawingState()); - return mLayer->getBufferSize(layerState); - } + Rect getBounds() const override { return mLayer->getBufferSize(StateSet::Drawing); } int getHeight() const override { - return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight(); + return mLayer->getBufferSize(StateSet::Drawing).getHeight(); } int getWidth() const override { - return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth(); + return mLayer->getBufferSize(StateSet::Drawing).getWidth(); } bool isSecure() const override { return false; } bool needsFiltering() const override { return mNeedsFiltering; } @@ -5278,7 +5272,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, const int uid = IPCThreadState::self()->getCallingUid(); const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; - if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) { + if (!forSystem && parent->getCurrentFlags() & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); return PERMISSION_DENIED; } @@ -5286,12 +5280,12 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, Rect crop(sourceCrop); if (sourceCrop.width() <= 0) { crop.left = 0; - crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth(); + crop.right = parent->getBufferSize(StateSet::Current).getWidth(); } if (sourceCrop.height() <= 0) { crop.top = 0; - crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight(); + crop.bottom = parent->getBufferSize(StateSet::Current).getHeight(); } int32_t reqWidth = crop.width() * frameScale; diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 7bfe0338f7..a6dcb7e327 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -101,22 +101,23 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation); const int32_t layerId(getLayerId(layer)); - addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(), - layer->mCurrentState.active_legacy.transform.ty()); - addDepthLocked(transaction, layerId, layer->mCurrentState.z); - addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a); + Mutex::Autolock lock(layer->mStateMutex); + addPositionLocked(transaction, layerId, layer->mState.current.active_legacy.transform.tx(), + layer->mState.current.active_legacy.transform.ty()); + addDepthLocked(transaction, layerId, layer->mState.current.z); + addAlphaLocked(transaction, layerId, layer->mState.current.color.a); addTransparentRegionLocked(transaction, layerId, - layer->mCurrentState.activeTransparentRegion_legacy); - addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack); - addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy); - addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius); - if (layer->mCurrentState.barrierLayer_legacy != nullptr) { + layer->mState.current.activeTransparentRegion_legacy); + addLayerStackLocked(transaction, layerId, layer->mState.current.layerStack); + addCropLocked(transaction, layerId, layer->mState.current.crop_legacy); + addCornerRadiusLocked(transaction, layerId, layer->mState.current.cornerRadius); + if (layer->mState.current.barrierLayer_legacy != nullptr) { addDeferTransactionLocked(transaction, layerId, - layer->mCurrentState.barrierLayer_legacy.promote(), - layer->mCurrentState.frameNumber_legacy); + layer->mState.current.barrierLayer_legacy.promote(), + layer->mState.current.frameNumber_legacy); } addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode()); - addFlagsLocked(transaction, layerId, layer->mCurrentState.flags); + addFlagsLocked(transaction, layerId, layer->mState.current.flags); } void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment, @@ -426,8 +427,9 @@ void SurfaceInterceptor::addSurfaceCreationLocked(Increment* increment, SurfaceCreation* creation(increment->mutable_surface_creation()); creation->set_id(getLayerId(layer)); creation->set_name(getLayerName(layer)); - creation->set_w(layer->mCurrentState.active_legacy.w); - creation->set_h(layer->mCurrentState.active_legacy.h); + Mutex::Autolock lock(layer->mStateMutex); + creation->set_w(layer->mState.current.active_legacy.w); + creation->set_h(layer->mState.current.active_legacy.h); } void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment, diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 6d4f7ef72e..63216a9294 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -178,11 +178,12 @@ public: using HotplugEvent = SurfaceFlinger::HotplugEvent; - auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; } - auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; } + auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mState.current; } + auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mState.drawing; } void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) { - layer->mDrawingState.sidebandStream = sidebandStream; + Mutex::Autolock lock(layer->mStateMutex); + layer->mState.drawing.sidebandStream = sidebandStream; layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream; } diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 09db37a9e8..6c971be3eb 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -28,7 +28,7 @@ import platform "platform.api" // API version (major.minor.patch) define VERSION_MAJOR 1 define VERSION_MINOR 1 -define VERSION_PATCH 93 +define VERSION_PATCH 94 // API limits define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 @@ -579,6 +579,10 @@ define NULL_HANDLE 0 @extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 @extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned" +// 201 +@extension("VK_KHR_swapchain_mutable_format") define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 +@extension("VK_KHR_swapchain_mutable_format") define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" + // 202 @extension("VK_NV_compute_shader_derivatives") define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 @extension("VK_NV_compute_shader_derivatives") define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" @@ -615,6 +619,10 @@ define NULL_HANDLE 0 @extension("VK_FUCHSIA_imagepipe_surface") define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 @extension("VK_FUCHSIA_imagepipe_surface") define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface" +// 219 +@extension("VK_EXT_fragment_density_map") define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +@extension("VK_EXT_fragment_density_map") define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" + // 222 @extension("VK_EXT_scalar_block_layout") define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 @extension("VK_EXT_scalar_block_layout") define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" @@ -736,6 +744,9 @@ enum VkImageLayout { //@extension("VK_NV_shading_rate_image") // 165 VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, + + //@extension("VK_EXT_fragment_density_map") // 219 + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, } enum VkAttachmentLoadOp { @@ -1861,6 +1872,11 @@ enum VkStructureType { //@extension("VK_FUCHSIA_imagepipe_surface") // 215 VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + //@extension("VK_EXT_fragment_density_map") // 219 + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + //@extension("VK_EXT_scalar_block_layout") VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, @@ -2478,6 +2494,9 @@ bitfield VkAccessFlagBits { VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, + //@extension("VK_EXT_fragment_density_map") // 219 + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + //@extension("VK_EXT_transform_feedback") // 29 VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, @@ -2573,6 +2592,9 @@ bitfield VkImageUsageFlagBits { //@extension("VK_NV_shading_rate_image") // 165 VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100, + + //@extension("VK_EXT_fragment_density_map") // 219 + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, } /// Image creation flags @@ -2614,12 +2636,17 @@ bitfield VkImageCreateFlagBits { //@extension("VK_NV_corner_sampled_image") // 51 VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, + + //@extension("VK_EXT_fragment_density_map") // 219 + VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, } /// Image view creation flags type VkFlags VkImageViewCreateFlags -//bitfield VkImageViewCreateFlagBits { -//} +bitfield VkImageViewCreateFlagBits { + //@extension("VK_EXT_fragment_density_map") // 219 + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, +} /// Pipeline creation flags type VkFlags VkPipelineCreateFlags @@ -2829,16 +2856,18 @@ bitfield VkPipelineStageFlagBits { //@extension("VK_EXT_conditional_rendering") // 82 VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, - //@extension("VK_NV_shading_rate_image") // 165 - VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, + //@extension("VK_NV_mesh_shader") // 203 + VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, + VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, //@extension("VK_NV_ray_tracing") // 166 VK_PIPELINE_STAGE_RAY_TRACING_BIT_NV = 0x00200000, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, - //@extension("VK_NV_mesh_shader") // 203 - VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, - VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, + //@extension("VK_NV_shading_rate_image") // 165 + VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, + + //@extension("VK_EXT_fragment_density_map") // 219 + VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, //@extension("VK_EXT_transform_feedback") // 29 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, @@ -2999,8 +3028,11 @@ type VkFlags VkPipelineLayoutCreateFlags /// Sampler creation flags type VkFlags VkSamplerCreateFlags -//bitfield VkSamplerCreateFlagBits { -//} +bitfield VkSamplerCreateFlagBits { + //@extension("VK_EXT_fragment_density_map") // 219 + VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, + VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, +} /// Render pass creation flags type VkFlags VkRenderPassCreateFlags @@ -3185,6 +3217,9 @@ bitfield VkSwapchainCreateFlagBitsKHR { //@vulkan1_1 VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + + //@extension("VK_KHR_swapchain_mutable_format") // 201 + VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, } @vulkan1_1 @@ -5028,7 +5063,7 @@ class VkDescriptorUpdateTemplateEntry { class VkDescriptorUpdateTemplateCreateInfo { VkStructureType sType - void* pNext + const void* pNext VkDescriptorUpdateTemplateCreateFlags flags u32 descriptorUpdateEntryCount const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries @@ -7674,6 +7709,31 @@ class VkImagePipeSurfaceCreateInfoFUCHSIA { platform.zx_handle_t imagePipeHandle } +@extension("VK_EXT_fragment_density_map") // 219 +class VkPhysicalDeviceFragmentDensityMapFeaturesEXT { + VkStructureType sType + void* pNext + VkBool32 fragmentDensityMap + VkBool32 fragmentDensityMapDynamic + VkBool32 fragmentDensityMapNonSubsampledImages +} + +@extension("VK_EXT_fragment_density_map") // 219 +class VkPhysicalDeviceFragmentDensityMapPropertiesEXT { + VkStructureType sType + void* pNext + VkExtent2D minFragmentDensityTexelSize + VkExtent2D maxFragmentDensityTexelSize + VkBool32 fragmentDensityInvocations +} + +@extension("VK_EXT_fragment_density_map") // 219 +class VkRenderPassFragmentDensityMapCreateInfoEXT { + VkStructureType sType + const void* pNext + VkAttachmentReference fragmentDensityMapAttachment +} + @extension("VK_EXT_scalar_block_layout") // 222 class VkPhysicalDeviceScalarBlockLayoutFeaturesEXT { VkStructureType sType diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h index 35c06649aa..bdbf80077c 100644 --- a/vulkan/include/vulkan/vulkan_core.h +++ b/vulkan/include/vulkan/vulkan_core.h @@ -43,7 +43,7 @@ extern "C" { #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) // Version of this file -#define VK_HEADER_VERSION 93 +#define VK_HEADER_VERSION 94 #define VK_NULL_HANDLE 0 @@ -454,6 +454,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -879,6 +882,7 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, @@ -1326,6 +1330,7 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, + VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, @@ -1349,6 +1354,7 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100, + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; @@ -1368,6 +1374,7 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, + VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, @@ -1452,6 +1459,7 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, + VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -1551,6 +1559,11 @@ typedef enum VkBufferUsageFlagBits { } VkBufferUsageFlagBits; typedef VkFlags VkBufferUsageFlags; typedef VkFlags VkBufferViewCreateFlags; + +typedef enum VkImageViewCreateFlagBits { + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, + VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageViewCreateFlagBits; typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef VkFlags VkPipelineCacheCreateFlags; @@ -1617,6 +1630,12 @@ typedef VkFlags VkColorComponentFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; + +typedef enum VkSamplerCreateFlagBits { + VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, + VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, + VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSamplerCreateFlagBits; typedef VkFlags VkSamplerCreateFlags; typedef enum VkDescriptorSetLayoutCreateFlagBits { @@ -1677,6 +1696,7 @@ typedef enum VkAccessFlagBits { VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -4357,7 +4377,7 @@ typedef struct VkDescriptorUpdateTemplateEntry { typedef struct VkDescriptorUpdateTemplateCreateInfo { VkStructureType sType; - void* pNext; + const void* pNext; VkDescriptorUpdateTemplateCreateFlags flags; uint32_t descriptorUpdateEntryCount; const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; @@ -4796,6 +4816,7 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) typedef enum VkSwapchainCreateFlagBitsKHR { VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSwapchainCreateFlagBitsKHR; typedef VkFlags VkSwapchainCreateFlagsKHR; @@ -6128,6 +6149,11 @@ typedef struct VkPhysicalDeviceDriverPropertiesKHR { +#define VK_KHR_swapchain_mutable_format 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" + + #define VK_KHR_vulkan_memory_model 1 #define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 2 #define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" @@ -8117,7 +8143,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( #define VK_NV_ray_tracing 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) -#define VK_NV_RAY_TRACING_SPEC_VERSION 2 +#define VK_NV_RAY_TRACING_SPEC_VERSION 3 #define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" #define VK_SHADER_UNUSED_NV (~0U) @@ -8807,6 +8833,34 @@ typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT { +#define VK_EXT_fragment_density_map 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" + +typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMap; + VkBool32 fragmentDensityMapDynamic; + VkBool32 fragmentDensityMapNonSubsampledImages; +} VkPhysicalDeviceFragmentDensityMapFeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT { + VkStructureType sType; + void* pNext; + VkExtent2D minFragmentDensityTexelSize; + VkExtent2D maxFragmentDensityTexelSize; + VkBool32 fragmentDensityInvocations; +} VkPhysicalDeviceFragmentDensityMapPropertiesEXT; + +typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkAttachmentReference fragmentDensityMapAttachment; +} VkRenderPassFragmentDensityMapCreateInfoEXT; + + + #define VK_EXT_scalar_block_layout 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" |