blob: 85e2fa77f512e1e8614ffaf85a8528274f7c8ee2 [file] [log] [blame]
Sungtak Lee8fc3ca42022-12-07 07:45:45 +00001/*
Sungtak Lee76937c62022-12-07 11:42:03 +00002 * Copyright (C) 2022 The Android Open Source Project
Sungtak Lee8fc3ca42022-12-07 07:45:45 +00003 *
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
Sungtak Lee76937c62022-12-07 11:42:03 +000017#pragma once
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000018
Sungtak Lee76937c62022-12-07 11:42:03 +000019#include <aidl/android/hardware/media/bufferpool2/BnAccessor.h>
20#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
21#include <bufferpool2/BufferPoolTypes.h>
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000022
Sungtak Lee76937c62022-12-07 11:42:03 +000023#include <memory>
24#include <map>
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000025#include <set>
Sungtak Lee76937c62022-12-07 11:42:03 +000026#include <condition_variable>
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000027
Sungtak Lee76937c62022-12-07 11:42:03 +000028#include "BufferPool.h"
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000029
Sungtak Lee76937c62022-12-07 11:42:03 +000030namespace aidl::android::hardware::media::bufferpool2::implementation {
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000031
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000032struct Connection;
Sungtak Lee76937c62022-12-07 11:42:03 +000033using ::aidl::android::hardware::media::bufferpool2::IObserver;
34using ::aidl::android::hardware::media::bufferpool2::IAccessor;
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000035
36/**
37 * Receives death notifications from remote connections.
38 * On death notifications, the connections are closed and used resources
39 * are released.
40 */
Sungtak Lee76937c62022-12-07 11:42:03 +000041struct ConnectionDeathRecipient {
42 ConnectionDeathRecipient();
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000043 /**
44 * Registers a newly connected connection from remote processes.
45 */
Sungtak Lee76937c62022-12-07 11:42:03 +000046 void add(int64_t connectionId, const std::shared_ptr<Accessor> &accessor);
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000047
48 /**
49 * Removes a connection.
50 */
51 void remove(int64_t connectionId);
52
Sungtak Lee76937c62022-12-07 11:42:03 +000053 void addCookieToConnection(void *cookie, int64_t connectionId);
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000054
Sungtak Lee76937c62022-12-07 11:42:03 +000055 void onDead(void *cookie);
56
57 AIBinder_DeathRecipient *getRecipient();
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000058
59private:
Sungtak Lee76937c62022-12-07 11:42:03 +000060 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
61
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000062 std::mutex mLock;
Sungtak Lee76937c62022-12-07 11:42:03 +000063 std::map<void *, std::set<int64_t>> mCookieToConnections;
64 std::map<int64_t, void *> mConnectionToCookie;
65 std::map<int64_t, const std::weak_ptr<Accessor>> mAccessors;
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000066};
67
68/**
69 * A buffer pool accessor which enables a buffer pool to communicate with buffer
70 * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
71 */
Sungtak Lee76937c62022-12-07 11:42:03 +000072struct Accessor : public BnAccessor {
73 // Methods from ::aidl::android::hardware::media::bufferpool2::IAccessor.
74 ::ndk::ScopedAStatus connect(const std::shared_ptr<IObserver>& in_observer,
75 IAccessor::ConnectionInfo* _aidl_return) override;
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000076
77 /**
78 * Creates a buffer pool accessor which uses the specified allocator.
79 *
80 * @param allocator buffer allocator.
81 */
82 explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
83
84 /** Destructs a buffer pool accessor. */
85 ~Accessor();
86
87 /** Returns whether the accessor is valid. */
88 bool isValid();
89
90 /** Invalidates all buffers which are owned by bufferpool */
Sungtak Lee76937c62022-12-07 11:42:03 +000091 BufferPoolStatus flush();
Sungtak Lee8fc3ca42022-12-07 07:45:45 +000092
93 /** Allocates a buffer from a buffer pool.
94 *
95 * @param connectionId the connection id of the client.
96 * @param params the allocation parameters.
97 * @param bufferId the id of the allocated buffer.
98 * @param handle the native handle of the allocated buffer.
99 *
100 * @return OK when a buffer is successfully allocated.
101 * NO_MEMORY when there is no memory.
102 * CRITICAL_ERROR otherwise.
103 */
Sungtak Lee76937c62022-12-07 11:42:03 +0000104 BufferPoolStatus allocate(
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000105 ConnectionId connectionId,
106 const std::vector<uint8_t>& params,
107 BufferId *bufferId,
108 const native_handle_t** handle);
109
110 /**
111 * Fetches a buffer for the specified transaction.
112 *
113 * @param connectionId the id of receiving connection(client).
114 * @param transactionId the id of the transfer transaction.
115 * @param bufferId the id of the buffer to be fetched.
116 * @param handle the native handle of the fetched buffer.
117 *
118 * @return OK when a buffer is successfully fetched.
119 * NO_MEMORY when there is no memory.
120 * CRITICAL_ERROR otherwise.
121 */
Sungtak Lee76937c62022-12-07 11:42:03 +0000122 BufferPoolStatus fetch(
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000123 ConnectionId connectionId,
124 TransactionId transactionId,
125 BufferId bufferId,
126 const native_handle_t** handle);
127
128 /**
129 * Makes a connection to the buffer pool. The buffer pool client uses the
130 * created connection in order to communicate with the buffer pool. An
131 * FMQ for buffer status message is also created for the client.
132 *
133 * @param observer client observer for buffer invalidation
134 * @param local true when a connection request comes from local process,
135 * false otherwise.
136 * @param connection created connection
137 * @param pConnectionId the id of the created connection
138 * @param pMsgId the id of the recent buffer pool message
139 * @param statusDescPtr FMQ descriptor for shared buffer status message
140 * queue between a buffer pool and the client.
141 * @param invDescPtr FMQ descriptor for buffer invalidation message
142 * queue from a buffer pool to the client.
143 *
144 * @return OK when a connection is successfully made.
145 * NO_MEMORY when there is no memory.
146 * CRITICAL_ERROR otherwise.
147 */
Sungtak Lee76937c62022-12-07 11:42:03 +0000148 BufferPoolStatus connect(
149 const std::shared_ptr<IObserver>& observer,
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000150 bool local,
Sungtak Lee76937c62022-12-07 11:42:03 +0000151 std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000152 uint32_t *pMsgId,
Sungtak Lee76937c62022-12-07 11:42:03 +0000153 StatusDescriptor* statusDescPtr,
154 InvalidationDescriptor* invDescPtr);
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000155
156 /**
157 * Closes the specified connection to the client.
158 *
159 * @param connectionId the id of the connection.
160 *
161 * @return OK when the connection is closed.
162 * CRITICAL_ERROR otherwise.
163 */
Sungtak Lee76937c62022-12-07 11:42:03 +0000164 BufferPoolStatus close(ConnectionId connectionId);
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000165
166 /**
Sungtak Lee76937c62022-12-07 11:42:03 +0000167 * Processes pending buffer status messages and performs periodic cache
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000168 * cleaning.
169 *
170 * @param clearCache if clearCache is true, it frees all buffers waiting
171 * to be recycled.
172 */
173 void cleanUp(bool clearCache);
174
175 /**
Sungtak Lee76937c62022-12-07 11:42:03 +0000176 * ACK on buffer invalidation messages
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000177 */
Sungtak Lee76937c62022-12-07 11:42:03 +0000178 void handleInvalidateAck();
179
180 /**
181 * Gets a death_recipient for remote connection death.
182 */
183 static std::shared_ptr<ConnectionDeathRecipient> getConnectionDeathRecipient();
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000184
185 static void createInvalidator();
186
187 static void createEvictor();
188
189private:
Sungtak Lee76937c62022-12-07 11:42:03 +0000190 // ConnectionId = pid : (timestamp_created + seqId)
191 // in order to guarantee uniqueness for each connection
192 static uint32_t sSeqId;
193
194 const std::shared_ptr<BufferPoolAllocator> mAllocator;
195 nsecs_t mScheduleEvictTs;
196 BufferPool mBufferPool;
197
198 struct AccessorInvalidator {
199 std::map<uint32_t, const std::weak_ptr<Accessor>> mAccessors;
200 std::mutex mMutex;
201 std::condition_variable mCv;
202 bool mReady;
203
204 AccessorInvalidator();
205 void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor> &accessor);
206 void delAccessor(uint32_t accessorId);
207 };
208
209 static std::unique_ptr<AccessorInvalidator> sInvalidator;
210
211 static void invalidatorThread(
212 std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
213 std::mutex &mutex,
214 std::condition_variable &cv,
215 bool &ready);
216
217 struct AccessorEvictor {
218 std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> mAccessors;
219 std::mutex mMutex;
220 std::condition_variable mCv;
221
222 AccessorEvictor();
223 void addAccessor(const std::weak_ptr<Accessor> &accessor, nsecs_t ts);
224 };
225
226 static std::unique_ptr<AccessorEvictor> sEvictor;
227
228 static void evictorThread(
229 std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
230 std::mutex &mutex,
231 std::condition_variable &cv);
232
233 void scheduleEvictIfNeeded();
234
235 friend struct BufferPool;
Sungtak Lee8fc3ca42022-12-07 07:45:45 +0000236};
237
Sungtak Lee76937c62022-12-07 11:42:03 +0000238} // namespace aidl::android::hardware::media::bufferpool2::implementation