blob: 10f274f569580df71d62fe1183b7546aad27548e [file] [log] [blame]
Fan Xucfbe0742018-11-21 15:03:32 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_BUFFER_HUB_DEFS_H_
18#define ANDROID_BUFFER_HUB_DEFS_H_
19
20#include <atomic>
21
22#pragma clang diagnostic push
23#pragma clang diagnostic ignored "-Wpacked"
24// TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr
25#include <dvr/dvr_api.h>
26#pragma clang diagnostic pop
27
28namespace android {
29
30namespace BufferHubDefs {
31
Tianyu Jianga99f9112018-12-13 18:23:07 -080032// Single buffer clients (up to 16) ownership signal.
33// 32-bit atomic unsigned int.
34// Each client takes 2 bits. The first bit locates in the first 16 bits of
Tianyu Jiangf377a762019-02-13 13:46:42 -080035// bufferState; the second bit locates in the last 16 bits of bufferState.
Fan Xud34a80a2018-12-04 11:32:39 -080036// Client states:
37// Gained state 11. Exclusive write state.
38// Posted state 10.
39// Acquired state 01. Shared read state.
40// Released state 00.
41//
42// MSB LSB
43// | |
44// v v
Tianyu Jianga99f9112018-12-13 18:23:07 -080045// [C15|...|C1|C0|C15| ... |C1|C0]
Fan Xud34a80a2018-12-04 11:32:39 -080046
47// Maximum number of clients a buffer can have.
Tianyu Jianga99f9112018-12-13 18:23:07 -080048static constexpr int kMaxNumberOfClients = 16;
Fan Xud34a80a2018-12-04 11:32:39 -080049
50// Definition of bit masks.
51// MSB LSB
52// | kHighBitsMask | kLowbitsMask |
53// v v v
Tianyu Jianga99f9112018-12-13 18:23:07 -080054// [b31| ... |b16|b15| ... |b0]
Fan Xud34a80a2018-12-04 11:32:39 -080055
Tianyu Jianga99f9112018-12-13 18:23:07 -080056// The location of lower 16 bits in the 32-bit buffer state.
57static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U;
Fan Xud34a80a2018-12-04 11:32:39 -080058
Tianyu Jianga99f9112018-12-13 18:23:07 -080059// The location of higher 16 bits in the 32-bit buffer state.
60static constexpr uint32_t kHighBitsMask = ~kLowbitsMask;
Fan Xud34a80a2018-12-04 11:32:39 -080061
62// The client bit mask of the first client.
Tianyu Jianga99f9112018-12-13 18:23:07 -080063static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
Fan Xud34a80a2018-12-04 11:32:39 -080064
65// Returns true if any of the client is in gained state.
Tianyu Jiang727ede42019-02-01 11:44:51 -080066static inline bool isAnyClientGained(uint32_t state) {
Tianyu Jiangf377a762019-02-13 13:46:42 -080067 uint32_t highBits = state >> kMaxNumberOfClients;
68 uint32_t lowBits = state & kLowbitsMask;
69 return highBits == lowBits && lowBits != 0U;
Fan Xud34a80a2018-12-04 11:32:39 -080070}
71
72// Returns true if the input client is in gained state.
Tianyu Jiang727ede42019-02-01 11:44:51 -080073static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
Fan Xud34a80a2018-12-04 11:32:39 -080074 return state == client_bit_mask;
75}
76
77// Returns true if any of the client is in posted state.
Tianyu Jiang727ede42019-02-01 11:44:51 -080078static inline bool isAnyClientPosted(uint32_t state) {
Tianyu Jiangf377a762019-02-13 13:46:42 -080079 uint32_t highBits = state >> kMaxNumberOfClients;
80 uint32_t lowBits = state & kLowbitsMask;
81 uint32_t postedOrAcquired = highBits ^ lowBits;
82 return postedOrAcquired & highBits;
Fan Xud34a80a2018-12-04 11:32:39 -080083}
84
85// Returns true if the input client is in posted state.
Tianyu Jiang727ede42019-02-01 11:44:51 -080086static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
Tianyu Jiangf377a762019-02-13 13:46:42 -080087 uint32_t clientBits = state & client_bit_mask;
88 if (clientBits == 0U) return false;
89 uint32_t lowBits = clientBits & kLowbitsMask;
90 return lowBits == 0U;
Fan Xud34a80a2018-12-04 11:32:39 -080091}
92
93// Return true if any of the client is in acquired state.
Tianyu Jiang727ede42019-02-01 11:44:51 -080094static inline bool isAnyClientAcquired(uint32_t state) {
Tianyu Jiangf377a762019-02-13 13:46:42 -080095 uint32_t highBits = state >> kMaxNumberOfClients;
96 uint32_t lowBits = state & kLowbitsMask;
97 uint32_t postedOrAcquired = highBits ^ lowBits;
98 return postedOrAcquired & lowBits;
Fan Xud34a80a2018-12-04 11:32:39 -080099}
100
101// Return true if the input client is in acquired state.
Tianyu Jiang727ede42019-02-01 11:44:51 -0800102static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
Tianyu Jiangf377a762019-02-13 13:46:42 -0800103 uint32_t clientBits = state & client_bit_mask;
104 if (clientBits == 0U) return false;
105 uint32_t highBits = clientBits & kHighBitsMask;
106 return highBits == 0U;
Fan Xud34a80a2018-12-04 11:32:39 -0800107}
108
Fan Xud34a80a2018-12-04 11:32:39 -0800109// Returns true if the input client is in released state.
Tianyu Jiang727ede42019-02-01 11:44:51 -0800110static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
Tianyu Jianga99f9112018-12-13 18:23:07 -0800111 return (state & client_bit_mask) == 0U;
Fan Xud34a80a2018-12-04 11:32:39 -0800112}
113
114// Returns the next available buffer client's client_state_masks.
115// @params union_bits. Union of all existing clients' client_state_masks.
Tianyu Jiang727ede42019-02-01 11:44:51 -0800116static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
Tianyu Jiangf377a762019-02-13 13:46:42 -0800117 uint32_t lowUnion = union_bits & kLowbitsMask;
118 if (lowUnion == kLowbitsMask) return 0U;
119 uint32_t incremented = lowUnion + 1U;
120 uint32_t difference = incremented ^ lowUnion;
121 uint32_t newLowBit = (difference + 1U) >> 1;
122 return newLowBit + (newLowBit << kMaxNumberOfClients);
Fan Xud34a80a2018-12-04 11:32:39 -0800123}
124
Fan Xucfbe0742018-11-21 15:03:32 -0800125struct __attribute__((aligned(8))) MetadataHeader {
126 // Internal data format, which can be updated as long as the size, padding and field alignment
127 // of the struct is consistent within the same ABI. As this part is subject for future updates,
128 // it's not stable cross Android version, so don't have it visible from outside of the Android
129 // platform (include Apps and vendor HAL).
130
131 // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
Tianyu Jiangf377a762019-02-13 13:46:42 -0800132 // bufferState.
133 std::atomic<uint32_t> bufferState;
Fan Xucfbe0742018-11-21 15:03:32 -0800134
Tianyu Jiangf377a762019-02-13 13:46:42 -0800135 // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
Fan Xucfbe0742018-11-21 15:03:32 -0800136 // bits are there for easier manipulation, but the value should be ignored.
Tianyu Jiangf377a762019-02-13 13:46:42 -0800137 std::atomic<uint32_t> fenceState;
Fan Xucfbe0742018-11-21 15:03:32 -0800138
139 // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
Tianyu Jiangf377a762019-02-13 13:46:42 -0800140 // activeClientsBitMask.
141 std::atomic<uint32_t> activeClientsBitMask;
Tianyu Jianga99f9112018-12-13 18:23:07 -0800142
143 // Explicit padding 4 bytes.
144 uint32_t padding;
Fan Xucfbe0742018-11-21 15:03:32 -0800145
146 // The index of the buffer queue where the buffer belongs to.
Tianyu Jiangf377a762019-02-13 13:46:42 -0800147 uint64_t queueIndex;
Fan Xucfbe0742018-11-21 15:03:32 -0800148
149 // Public data format, which should be updated with caution. See more details in dvr_api.h
150 DvrNativeBufferMetadata metadata;
151};
152
Tianyu Jianga99f9112018-12-13 18:23:07 -0800153static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
Fan Xucfbe0742018-11-21 15:03:32 -0800154static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
155
Fan Xuefce32e2018-12-12 14:34:16 -0800156/**
157 * android.frameworks.bufferhub@1.0::BufferTraits.bufferInfo is an opaque handle. See
158 * https://cs.corp.google.com/android/frameworks/hardware/interfaces/bufferhub/1.0/types.hal for
159 * more details about android.frameworks.bufferhub@1.0::BufferTraits.
160 *
161 * This definition could be changed, but implementation of BufferHubService::buildBufferInfo
162 * (frameworks/native/services/bufferhub), VtsHalBufferHubV1_0TargetTest
163 * (frameworks/hardware/interfaces/bufferhub) and BufferHubBuffer::readBufferTraits (libui) will
164 * also need to be updated.
165 *
166 * It's definition should follow the following format:
167 * {
Fan Xu5cf47bc2019-01-15 15:02:15 -0800168 * NumFds = 2,
Fan Xuefce32e2018-12-12 14:34:16 -0800169 * NumInts = 3,
170 * data[0] = Ashmem fd for BufferHubMetadata,
Fan Xu5cf47bc2019-01-15 15:02:15 -0800171 * data[1] = event fd,
172 * data[2] = buffer id,
173 * data[3] = client state bit mask,
174 * data[4] = user metadata size,
Fan Xuefce32e2018-12-12 14:34:16 -0800175 * }
176 */
Fan Xu5cf47bc2019-01-15 15:02:15 -0800177static constexpr int kBufferInfoNumFds = 2;
Fan Xuefce32e2018-12-12 14:34:16 -0800178static constexpr int kBufferInfoNumInts = 3;
179
Fan Xucfbe0742018-11-21 15:03:32 -0800180} // namespace BufferHubDefs
181
182} // namespace android
183
184#endif // ANDROID_BUFFER_HUB_DEFS_H_