blob: 2d53c5f88e10a28a33315d4ae961329981dfd859 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//#define LOG_NDEBUG 0
#define LOG_TAG "V4L2PluginStore"
#include <inttypes.h>
#include <map>
#include <memory>
#include <mutex>
#include <C2AllocatorGralloc.h>
#include <C2BufferPriv.h>
#include <log/log.h>
#include <v4l2_codec2/plugin_store/C2VdaBqBlockPool.h>
#include <v4l2_codec2/plugin_store/C2VdaPooledBlockPool.h>
#include <v4l2_codec2/plugin_store/V4L2AllocatorId.h>
#include <v4l2_codec2/plugin_store/VendorAllocatorLoader.h>
namespace android {
C2Allocator* createAllocator(C2Allocator::id_t allocatorId) {
ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
static std::unique_ptr<VendorAllocatorLoader> sAllocatorLoader =
VendorAllocatorLoader::Create();
if (sAllocatorLoader != nullptr) {
ALOGD("%s(): Create C2Allocator (id=%u) from VendorAllocatorLoader", __func__, allocatorId);
return sAllocatorLoader->createAllocator(allocatorId);
}
ALOGI("%s(): Fallback to create C2AllocatorGralloc(id=%u)", __func__, allocatorId);
return new C2AllocatorGralloc(allocatorId, true);
}
std::shared_ptr<C2Allocator> fetchAllocator(C2Allocator::id_t allocatorId) {
ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
static std::mutex sMutex;
static std::map<C2Allocator::id_t, std::weak_ptr<C2Allocator>> sCacheAllocators;
std::lock_guard<std::mutex> lock(sMutex);
std::shared_ptr<C2Allocator> allocator;
auto iter = sCacheAllocators.find(allocatorId);
if (iter != sCacheAllocators.end()) {
allocator = iter->second.lock();
if (allocator != nullptr) {
return allocator;
}
}
allocator.reset(createAllocator(allocatorId));
sCacheAllocators[allocatorId] = allocator;
return allocator;
}
C2BlockPool* createBlockPool(C2Allocator::id_t allocatorId, C2BlockPool::local_id_t poolId) {
ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);
std::shared_ptr<C2Allocator> allocator = fetchAllocator(allocatorId);
if (allocator == nullptr) {
ALOGE("%s(): Failed to create allocator id=%u", __func__, allocatorId);
return nullptr;
}
switch (allocatorId) {
case V4L2AllocatorId::V4L2_BUFFERPOOL:
return new C2VdaPooledBlockPool(allocator, poolId);
case V4L2AllocatorId::V4L2_BUFFERQUEUE:
return new C2VdaBqBlockPool(allocator, poolId);
case V4L2AllocatorId::SECURE_LINEAR:
return new C2PooledBlockPool(allocator, poolId);
case V4L2AllocatorId::SECURE_GRAPHIC:
return new C2VdaBqBlockPool(allocator, poolId);
default:
ALOGE("%s(): Unknown allocator id=%u", __func__, allocatorId);
return nullptr;
}
}
} // namespace android
extern "C" ::C2BlockPool* CreateBlockPool(::C2Allocator::id_t allocatorId,
::C2BlockPool::local_id_t poolId) {
ALOGV("%s(allocatorId=%d, poolId=%" PRIu64 ")", __func__, allocatorId, poolId);
return ::android::createBlockPool(allocatorId, poolId);
}
extern "C" ::C2Allocator* CreateAllocator(::C2Allocator::id_t allocatorId, ::c2_status_t* status) {
ALOGV("%s(allocatorId=%d)", __func__, allocatorId);
::C2Allocator* res = ::android::createAllocator(allocatorId);
*status = (res != nullptr) ? C2_OK : C2_BAD_INDEX;
return res;
}