blob: 0ebe347e0872e8ca8125ddf866a1b5fe004082d7 [file] [log] [blame]
Sungtak Lee97e1dfb2022-12-07 07:45:45 +00001/*
Sungtak Lee8878a132022-12-07 11:42:03 +00002 * Copyright (C) 2022 The Android Open Source Project
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +000017#pragma once
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000018
Sungtak Lee8878a132022-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 Lee97e1dfb2022-12-07 07:45:45 +000022
Sungtak Lee8878a132022-12-07 11:42:03 +000023#include <memory>
24#include <map>
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000025#include <set>
Sungtak Lee8878a132022-12-07 11:42:03 +000026#include <condition_variable>
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000027
Sungtak Lee8878a132022-12-07 11:42:03 +000028#include "BufferPool.h"
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000029
Sungtak Lee8878a132022-12-07 11:42:03 +000030namespace aidl::android::hardware::media::bufferpool2::implementation {
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000031
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000032struct Connection;
Sungtak Lee8878a132022-12-07 11:42:03 +000033using ::aidl::android::hardware::media::bufferpool2::IObserver;
34using ::aidl::android::hardware::media::bufferpool2::IAccessor;
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +000041struct ConnectionDeathRecipient {
42 ConnectionDeathRecipient();
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000043 /**
44 * Registers a newly connected connection from remote processes.
45 */
Sungtak Lee8878a132022-12-07 11:42:03 +000046 void add(int64_t connectionId, const std::shared_ptr<Accessor> &accessor);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000047
48 /**
49 * Removes a connection.
50 */
51 void remove(int64_t connectionId);
52
Sungtak Lee8878a132022-12-07 11:42:03 +000053 void addCookieToConnection(void *cookie, int64_t connectionId);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000054
Sungtak Lee8878a132022-12-07 11:42:03 +000055 void onDead(void *cookie);
56
57 AIBinder_DeathRecipient *getRecipient();
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000058
59private:
Sungtak Lee8878a132022-12-07 11:42:03 +000060 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
61
Sungtak Lee97e1dfb2022-12-07 07:45:45 +000062 std::mutex mLock;
Sungtak Lee8878a132022-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 Lee97e1dfb2022-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 Lee8878a132022-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 Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +000091 BufferPoolStatus flush();
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +0000104 BufferPoolStatus allocate(
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +0000122 BufferPoolStatus fetch(
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +0000148 BufferPoolStatus connect(
149 const std::shared_ptr<IObserver>& observer,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000150 bool local,
Sungtak Lee8878a132022-12-07 11:42:03 +0000151 std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000152 uint32_t *pMsgId,
Sungtak Lee8878a132022-12-07 11:42:03 +0000153 StatusDescriptor* statusDescPtr,
154 InvalidationDescriptor* invDescPtr);
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +0000164 BufferPoolStatus close(ConnectionId connectionId);
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000165
166 /**
Sungtak Lee8878a132022-12-07 11:42:03 +0000167 * Processes pending buffer status messages and performs periodic cache
Sungtak Lee97e1dfb2022-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 Lee8878a132022-12-07 11:42:03 +0000176 * ACK on buffer invalidation messages
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000177 */
Sungtak Lee8878a132022-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 Lee97e1dfb2022-12-07 07:45:45 +0000184
185 static void createInvalidator();
186
187 static void createEvictor();
188
189private:
Sungtak Lee8878a132022-12-07 11:42:03 +0000190 // ConnectionId = pid : (timestamp_created + seqId)
191 // in order to guarantee uniqueness for each connection
Sungtak Lee5e104e42024-06-07 04:46:23 +0000192 struct ConnectionIdGenerator {
193 int32_t mPid;
194 uint32_t mSeqId;
195 std::mutex mLock;
196
197 ConnectionIdGenerator();
198 ConnectionId getConnectionId();
199 };
Sungtak Lee8878a132022-12-07 11:42:03 +0000200
201 const std::shared_ptr<BufferPoolAllocator> mAllocator;
202 nsecs_t mScheduleEvictTs;
203 BufferPool mBufferPool;
204
205 struct AccessorInvalidator {
206 std::map<uint32_t, const std::weak_ptr<Accessor>> mAccessors;
207 std::mutex mMutex;
208 std::condition_variable mCv;
209 bool mReady;
210
211 AccessorInvalidator();
212 void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor> &accessor);
213 void delAccessor(uint32_t accessorId);
214 };
215
216 static std::unique_ptr<AccessorInvalidator> sInvalidator;
217
218 static void invalidatorThread(
219 std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
220 std::mutex &mutex,
221 std::condition_variable &cv,
222 bool &ready);
223
224 struct AccessorEvictor {
225 std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> mAccessors;
226 std::mutex mMutex;
227 std::condition_variable mCv;
228
229 AccessorEvictor();
230 void addAccessor(const std::weak_ptr<Accessor> &accessor, nsecs_t ts);
231 };
232
233 static std::unique_ptr<AccessorEvictor> sEvictor;
234
235 static void evictorThread(
236 std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
237 std::mutex &mutex,
238 std::condition_variable &cv);
239
240 void scheduleEvictIfNeeded();
241
242 friend struct BufferPool;
Sungtak Lee97e1dfb2022-12-07 07:45:45 +0000243};
244
Sungtak Lee8878a132022-12-07 11:42:03 +0000245} // namespace aidl::android::hardware::media::bufferpool2::implementation