xref: /aosp_15_r20/external/v4l2_codec2/plugin_store/V4L2PluginStore.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "V4L2PluginStore"
7 
8 #include <inttypes.h>
9 
10 #include <map>
11 #include <memory>
12 #include <mutex>
13 
14 #include <C2AllocatorGralloc.h>
15 #include <C2BqBufferPriv.h>
16 #include <C2BufferPriv.h>
17 #include <log/log.h>
18 
19 #include <v4l2_codec2/plugin_store/V4L2AllocatorId.h>
20 #include <v4l2_codec2/plugin_store/VendorAllocatorLoader.h>
21 
22 namespace android {
23 
24 static std::mutex sAllocatorLoaderMutex;
25 
26 // Using optional because in the case of library being no availiable, we do not want to retry its search.
27 static std::optional<std::unique_ptr<VendorAllocatorLoader>> sAllocatorLoader = std::nullopt;
28 
getAllocatorLoader()29 const std::unique_ptr<VendorAllocatorLoader>& getAllocatorLoader() {
30     {
31         std::lock_guard<std::mutex> lock(sAllocatorLoaderMutex);
32 
33         if (sAllocatorLoader == std::nullopt) {
34             sAllocatorLoader = VendorAllocatorLoader::Create();
35         }
36     }
37 
38     return *sAllocatorLoader;
39 }
40 
createAllocator(C2Allocator::id_t allocatorId)41 C2Allocator* createAllocator(C2Allocator::id_t allocatorId) {
42     ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
43 
44     auto& allocatorLoader = getAllocatorLoader();
45     if (allocatorLoader != nullptr) {
46         ALOGD("%s(): Create C2Allocator (id=%u) from VendorAllocatorLoader", __func__, allocatorId);
47         return allocatorLoader->createAllocator(allocatorId);
48     }
49 
50     ALOGI("%s(): Fallback to create C2AllocatorGralloc(id=%u)", __func__, allocatorId);
51     return new C2AllocatorGralloc(allocatorId, true);
52 }
53 
fetchAllocator(C2Allocator::id_t allocatorId)54 std::shared_ptr<C2Allocator> fetchAllocator(C2Allocator::id_t allocatorId) {
55     ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
56     static std::mutex sMutex;
57     static std::map<C2Allocator::id_t, std::weak_ptr<C2Allocator>> sCacheAllocators;
58 
59     std::lock_guard<std::mutex> lock(sMutex);
60 
61     std::shared_ptr<C2Allocator> allocator;
62     auto iter = sCacheAllocators.find(allocatorId);
63     if (iter != sCacheAllocators.end()) {
64         allocator = iter->second.lock();
65         if (allocator != nullptr) {
66             return allocator;
67         }
68     }
69 
70     allocator.reset(createAllocator(allocatorId));
71     sCacheAllocators[allocatorId] = allocator;
72     return allocator;
73 }
74 
createBlockPool(C2Allocator::id_t allocatorId,C2BlockPool::local_id_t poolId)75 C2BlockPool* createBlockPool(C2Allocator::id_t allocatorId, C2BlockPool::local_id_t poolId) {
76     ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);
77 
78     auto& allocatorLoader = getAllocatorLoader();
79     if (allocatorLoader != nullptr) {
80         ALOGD("%s(): Create C2BlockPool (id=%u) from VendorAllocatorLoader", __func__, allocatorId);
81         C2BlockPool* pool = allocatorLoader->createBlockPool(allocatorId, poolId);
82         ;
83         if (pool != nullptr) {
84             return pool;
85         }
86     }
87 
88     std::shared_ptr<C2Allocator> allocator = fetchAllocator(allocatorId);
89     if (allocator == nullptr) {
90         ALOGE("%s(): Failed to create allocator id=%u", __func__, allocatorId);
91         return nullptr;
92     }
93 
94     switch (allocatorId) {
95     case V4L2AllocatorId::SECURE_LINEAR:
96         return new C2PooledBlockPool(allocator, poolId);
97 
98     case V4L2AllocatorId::SECURE_GRAPHIC:
99         return new C2BufferQueueBlockPool(allocator, poolId);
100 
101     default:
102         ALOGE("%s(): Unknown allocator id=%u", __func__, allocatorId);
103         return nullptr;
104     }
105 }
106 
107 }  // namespace android
108 
CreateBlockPool(::C2Allocator::id_t allocatorId,::C2BlockPool::local_id_t poolId)109 extern "C" ::C2BlockPool* CreateBlockPool(::C2Allocator::id_t allocatorId,
110                                           ::C2BlockPool::local_id_t poolId) {
111     ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);
112     return ::android::createBlockPool(allocatorId, poolId);
113 }
114 
CreateAllocator(::C2Allocator::id_t allocatorId,::c2_status_t * status)115 extern "C" ::C2Allocator* CreateAllocator(::C2Allocator::id_t allocatorId, ::c2_status_t* status) {
116     ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
117 
118     ::C2Allocator* res = ::android::createAllocator(allocatorId);
119     *status = (res != nullptr) ? C2_OK : C2_BAD_INDEX;
120     return res;
121 }
122