/* * 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 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" // TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr #include #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 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 fenceState; // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in // activeClientsBitMask. std::atomic 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_