| /* |
| * 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 16) ownership signal. |
| // 32-bit atomic unsigned int. |
| // Each client takes 2 bits. The first bit locates in the first 16 bits of |
| // bufferState; the second bit locates in the last 16 bits of bufferState. |
| // Client states: |
| // Gained state 11. Exclusive write state. |
| // Posted state 10. |
| // Acquired state 01. Shared read state. |
| // Released state 00. |
| // |
| // MSB LSB |
| // | | |
| // v v |
| // [C15|...|C1|C0|C15| ... |C1|C0] |
| |
| // Maximum number of clients a buffer can have. |
| static constexpr int kMaxNumberOfClients = 16; |
| |
| // Definition of bit masks. |
| // MSB LSB |
| // | kHighBitsMask | kLowbitsMask | |
| // v v v |
| // [b31| ... |b16|b15| ... |b0] |
| |
| // The location of lower 16 bits in the 32-bit buffer state. |
| static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U; |
| |
| // The location of higher 16 bits in the 32-bit buffer state. |
| static constexpr uint32_t kHighBitsMask = ~kLowbitsMask; |
| |
| // The client bit mask of the first client. |
| static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U; |
| |
| // Returns true if any of the client is in gained state. |
| static inline bool isAnyClientGained(uint32_t state) { |
| uint32_t highBits = state >> kMaxNumberOfClients; |
| uint32_t lowBits = state & kLowbitsMask; |
| return highBits == lowBits && lowBits != 0U; |
| } |
| |
| // Returns true if the input client is in gained state. |
| static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) { |
| return state == client_bit_mask; |
| } |
| |
| // Returns true if any of the client is in posted state. |
| static inline bool isAnyClientPosted(uint32_t state) { |
| uint32_t highBits = state >> kMaxNumberOfClients; |
| uint32_t lowBits = state & kLowbitsMask; |
| uint32_t postedOrAcquired = highBits ^ lowBits; |
| return postedOrAcquired & highBits; |
| } |
| |
| // Returns true if the input client is in posted state. |
| static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) { |
| uint32_t clientBits = state & client_bit_mask; |
| if (clientBits == 0U) return false; |
| uint32_t lowBits = clientBits & kLowbitsMask; |
| return lowBits == 0U; |
| } |
| |
| // Return true if any of the client is in acquired state. |
| static inline bool isAnyClientAcquired(uint32_t state) { |
| uint32_t highBits = state >> kMaxNumberOfClients; |
| uint32_t lowBits = state & kLowbitsMask; |
| uint32_t postedOrAcquired = highBits ^ lowBits; |
| return postedOrAcquired & lowBits; |
| } |
| |
| // Return true if the input client is in acquired state. |
| static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) { |
| uint32_t clientBits = state & client_bit_mask; |
| if (clientBits == 0U) return false; |
| uint32_t highBits = clientBits & kHighBitsMask; |
| return highBits == 0U; |
| } |
| |
| // Returns true if the input client is in released state. |
| static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) { |
| return (state & client_bit_mask) == 0U; |
| } |
| |
| // Returns the next available buffer client's client_state_masks. |
| // @params union_bits. Union of all existing clients' client_state_masks. |
| static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) { |
| uint32_t lowUnion = union_bits & kLowbitsMask; |
| if (lowUnion == kLowbitsMask) return 0U; |
| uint32_t incremented = lowUnion + 1U; |
| uint32_t difference = incremented ^ lowUnion; |
| uint32_t newLowBit = (difference + 1U) >> 1; |
| return newLowBit + (newLowBit << 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 |
| // bufferState. |
| std::atomic<uint32_t> bufferState; |
| |
| // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32 |
| // bits are there for easier manipulation, but the value should be ignored. |
| std::atomic<uint32_t> fenceState; |
| |
| // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in |
| // activeClientsBitMask. |
| std::atomic<uint32_t> activeClientsBitMask; |
| |
| // Explicit padding 4 bytes. |
| uint32_t padding; |
| |
| // The index of the buffer queue where the buffer belongs to. |
| uint64_t queueIndex; |
| |
| // Public data format, which should be updated with caution. See more details in dvr_api.h |
| DvrNativeBufferMetadata metadata; |
| }; |
| |
| static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size"); |
| static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader); |
| |
| /** |
| * android.frameworks.bufferhub@1.0::BufferTraits.bufferInfo is an opaque handle. See |
| * https://cs.corp.google.com/android/frameworks/hardware/interfaces/bufferhub/1.0/types.hal for |
| * more details about android.frameworks.bufferhub@1.0::BufferTraits. |
| * |
| * This definition could be changed, but implementation of BufferHubService::buildBufferInfo |
| * (frameworks/native/services/bufferhub), VtsHalBufferHubV1_0TargetTest |
| * (frameworks/hardware/interfaces/bufferhub) and BufferHubBuffer::readBufferTraits (libui) will |
| * also need to be updated. |
| * |
| * It's definition should follow the following format: |
| * { |
| * NumFds = 2, |
| * NumInts = 3, |
| * data[0] = Ashmem fd for BufferHubMetadata, |
| * data[1] = event fd, |
| * data[2] = buffer id, |
| * data[3] = client state bit mask, |
| * data[4] = user metadata size, |
| * } |
| */ |
| static constexpr int kBufferInfoNumFds = 2; |
| static constexpr int kBufferInfoNumInts = 3; |
| |
| } // namespace BufferHubDefs |
| |
| } // namespace android |
| |
| #endif // ANDROID_BUFFER_HUB_DEFS_H_ |