C2Store.cpp revision a165b1a2ce351042803e7150ce425e589c89a08e
14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2017 The Android Open Source Project
34344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
44344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Licensed under the Apache License, Version 2.0 (the "License");
54344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * you may not use this file except in compliance with the License.
64344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * You may obtain a copy of the License at
74344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
84344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *      http://www.apache.org/licenses/LICENSE-2.0
94344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Unless required by applicable law or agreed to in writing, software
114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * distributed under the License is distributed on an "AS IS" BASIS,
124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * See the License for the specific language governing permissions and
144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * limitations under the License.
154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#define LOG_TAG "C2Store"
1839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#define LOG_NDEBUG 0
1939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#include <utils/Log.h>
2039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2AllocatorGralloc.h>
224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2AllocatorIon.h>
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2BufferPriv.h>
2439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee#include <C2BqBufferPriv.h>
254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2Component.h>
2651ea56a991d6371e35c8d0bb5001e721cc63f8eeLajos Molnar#include <C2Config.h>
274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2PlatformSupport.h>
289fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim#include <util/C2InterfaceHelper.h>
294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <dlfcn.h>
31493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar#include <unistd.h> // getpagesize
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <map>
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <memory>
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <mutex>
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
40493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar * Returns the preferred component store in this process to access its interface.
41493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar */
42493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore();
43493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
44493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar/**
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * The platform allocator store provides basic allocator-types for the framework based on ion and
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * gralloc. Allocators are not meant to be updatable.
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Provide allocator based on ashmem
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Make this allocator store extendable
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
54493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2PlatformAllocatorStoreImpl();
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t fetchAllocator(
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const override {
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override {
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return "android.allocator-store";
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
68493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    void setComponentStore(std::shared_ptr<C2ComponentStore> store);
69493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
70493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    ~C2PlatformAllocatorStoreImpl() override = default;
71493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton ion allocator
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchIonAllocator();
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton gralloc allocator
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
78493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
7938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    /// returns a shared-singleton bufferqueue supporting gralloc allocator
8038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
8138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
82493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    /// component store to use
83493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
84493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                                        // dependencies
85493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreReadLock; // must protect only read/write of _mComponentStore
86493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> _mComponentStore;
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    allocator->reset();
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: should we implement a generic registry for all, and use that?
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::ION:
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_LINEAR:
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchIonAllocator();
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::GRALLOC:
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_GRAPHIC:
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchGrallocAllocator();
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    case C2PlatformAllocatorStore::BUFFERQUEUE:
10838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        *allocator = fetchBufferQueueAllocator();
10938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        break;
11038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (*allocator == nullptr) {
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NO_MEMORY;
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
120493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
121493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
122493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::mutex gIonAllocatorMutex;
123493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::weak_ptr<C2AllocatorIon> gIonAllocator;
124493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
125493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid UseComponentStoreForIonAllocator(
126493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        const std::shared_ptr<C2AllocatorIon> allocator,
127493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> store) {
128493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2AllocatorIon::UsageMapperFn mapper;
129493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t minUsage = 0;
130493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t maxUsage = C2MemoryUsage(C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE).expected;
131493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    size_t blockSize = getpagesize();
132493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
133493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // query min and max usage as well as block size via supported values
134493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2StoreIonUsageInfo usageInfo;
135493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::vector<C2FieldSupportedValuesQuery> query = {
136493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.usage)),
137493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.capacity)),
138493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
139493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    c2_status_t res = store->querySupportedValues_sm(query);
140493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (res == C2_OK) {
141493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[0].status == C2_OK) {
142493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[0].values;
143493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::FLAGS && !fsv.values.empty()) {
144493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                minUsage = fsv.values[0].u64;
145493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                maxUsage = 0;
146493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                for (C2Value::Primitive v : fsv.values) {
147493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    maxUsage |= v.u64;
148493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
149493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
150493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
151493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[1].status == C2_OK) {
152493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[1].values;
153493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::RANGE && fsv.range.step.u32 > 0) {
154493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                blockSize = fsv.range.step.u32;
155493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
156493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
157493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
158493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        mapper = [store](C2MemoryUsage usage, size_t capacity,
159493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                         size_t *align, unsigned *heapMask, unsigned *flags) -> c2_status_t {
160493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (capacity > UINT32_MAX) {
161493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                return C2_BAD_VALUE;
162493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
163493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            C2StoreIonUsageInfo usageInfo = { usage.expected, capacity };
164493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::vector<std::unique_ptr<C2SettingResult>> failures; // TODO: remove
165493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            c2_status_t res = store->config_sm({&usageInfo}, &failures);
166493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (res == C2_OK) {
167493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *align = usageInfo.minAlignment;
168493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *heapMask = usageInfo.heapMask;
169493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *flags = usageInfo.allocFlags;
170493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
171493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            return res;
172493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        };
173493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
174493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
175493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    allocator->setUsageMapper(mapper, minUsage, maxUsage, blockSize);
176493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
177493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
178493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
179493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
180493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid C2PlatformAllocatorStoreImpl::setComponentStore(std::shared_ptr<C2ComponentStore> store) {
181493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // technically this set lock is not needed, but is here for safety in case we add more
182493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // getter orders
183493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(_mComponentStoreSetLock);
184493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
185493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
186493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        _mComponentStore = store;
187493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
188493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator;
189493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
190493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
191493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocator = gIonAllocator.lock();
192493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
193493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocator) {
194493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, store);
195493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
196493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
197493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
199493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
200493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator = gIonAllocator.lock();
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
202493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> componentStore;
203493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        {
204493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
205493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            componentStore = _mComponentStore;
206493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
208493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, componentStore);
209493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gIonAllocator = allocator;
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2Allocator> grallocAllocator;
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        grallocAllocator = allocator;
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
22638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Leestd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchBufferQueueAllocator() {
22738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::mutex mutex;
22838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::weak_ptr<C2Allocator> grallocAllocator;
22938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::lock_guard<std::mutex> lock(mutex);
23038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
23138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    if (allocator == nullptr) {
23238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        allocator = std::make_shared<C2AllocatorGralloc>(
23338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, true);
23438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        grallocAllocator = allocator;
23538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    }
23638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    return allocator;
23738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee}
23838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
239493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
240493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPreferredComponentStoreMutex;
241493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
242493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
243493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPlatformAllocatorStoreMutex;
244493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::weak_ptr<C2PlatformAllocatorStoreImpl> gPlatformAllocatorStore;
245493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
246493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
248493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
249493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> store = gPlatformAllocatorStore.lock();
250493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (store == nullptr) {
251493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store = std::make_shared<C2PlatformAllocatorStoreImpl>();
252493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store->setComponentStore(GetPreferredCodec2ComponentStore());
253493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPlatformAllocatorStore = store;
254493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
255493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return store;
256493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
257493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
258493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> componentStore) {
259493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    static std::mutex mutex;
260493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(mutex); // don't interleve set-s
261493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
262493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update preferred store
263493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
264493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
265493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPreferredComponentStore = componentStore;
266493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
267493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
268493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update platform allocator's store as well if it is alive
269493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> allocatorStore;
270493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
271493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
272493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore = gPlatformAllocatorStore.lock();
273493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
274493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocatorStore) {
275493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore->setComponentStore(componentStore);
276493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
277493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
278493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
279493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore() {
280493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
281493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return gPreferredComponentStore ? gPreferredComponentStore : GetCodec2PlatformComponentStore();
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
28439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leenamespace {
28539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
28639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeclass _C2BlockPoolCache {
28739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leepublic:
28839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
28939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
29039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t _createBlockPool(
2918060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
2928060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
2938060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t poolId,
29439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
29539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2AllocatorStore> allocatorStore =
29639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                GetCodec2PlatformAllocatorStore();
29739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2Allocator> allocator;
29839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        c2_status_t res = C2_NOT_FOUND;
29939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
30039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        switch(allocatorId) {
30139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            case C2PlatformAllocatorStore::ION:
30239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
30339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
30439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
305878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
30639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2PooledBlockPool>(
30739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
30839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
309878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3108060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
31139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
31239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
31338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            case C2PlatformAllocatorStore::BUFFERQUEUE:
31439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
31538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                        C2PlatformAllocatorStore::BUFFERQUEUE, &allocator);
31639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
317878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
31839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2BufferQueueBlockPool>(
31939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
32039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
321878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3228060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
32339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
32439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
32539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            default:
32639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
32739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
32839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return res;
32939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
33039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
33139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t createBlockPool(
3328060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
3338060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3348060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
3358060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        return _createBlockPool(allocatorId, component, mBlockPoolSeqId++, pool);
33639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
33739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3388060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    bool getBlockPool(
3398060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t blockPoolId,
3408060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3418060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
34289eabf0d6b92d93eced043ce4abd2ac527c0374aPawin Vongmasa        // TODO: use one iterator for multiple blockpool type scalability.
3438060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        std::shared_ptr<C2BlockPool> ptr;
344878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        auto it = mBlockPools.find(blockPoolId);
345878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (it != mBlockPools.end()) {
346878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            ptr = it->second.lock();
3478060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!ptr) {
348878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                mBlockPools.erase(it);
3498060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
3508060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
3518060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
3528060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
3538060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    *pool = ptr;
3548060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
3558060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
35639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
35739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
35839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return false;
35939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
36039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
36139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeprivate:
36239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    C2BlockPool::local_id_t mBlockPoolSeqId;
3638060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee
364878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
3658060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<const C2Component>> mComponents;
36639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee};
36739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
36839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
36939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::make_unique<_C2BlockPoolCache>();
37039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::mutex sBlockPoolCacheMutex;
37139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
37239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee} // anynymous namespace
37339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t GetCodec2BlockPool(
3754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
3764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
37839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
3794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
3804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator;
3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = C2_NOT_FOUND;
3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
38339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    if (id >= C2BlockPool::PLATFORM_START) {
3848060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        if (sBlockPoolCache->getBlockPool(id, component, pool)) {
38539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            return C2_OK;
38639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
38739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
38839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_LINEAR:
3914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
3944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
3964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_GRAPHIC:
3974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
40239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    // TODO: remove this. this is temporary
40339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    case C2BlockPool::PLATFORM_START:
4048060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        res = sBlockPoolCache->_createBlockPool(
40538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, component, id, pool);
40639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        break;
4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t CreateCodec2BlockPool(
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlatformAllocatorStore::id_t allocatorId,
4154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component> component,
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
41939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
4208060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    return sBlockPoolCache->createBlockPool(allocatorId, component, pool);
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformComponentStore : public C2ComponentStore {
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override;
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedValues_sm(
4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedParams_nb(
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t query_sm(
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &stackParams,
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param::Index> &heapParamIndices,
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createInterface(
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createComponent(
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2Component> *const component) override;
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t copyBuffer(
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t config_sm(
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &params,
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2PlatformComponentStore();
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual ~C2PlatformComponentStore() override = default;
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loaded component module.
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo provide a way to add traits to known components here to avoid loading the .so-s
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for listComponents
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentModule : public C2ComponentFactory,
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            public std::enable_shared_from_this<ComponentModule> {
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createComponent(
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2Component> *component,
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createInterface(
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \returns the traits of the component in this module.
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component::Traits> getTraits();
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates an uninitialized component module.
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param name[in]  component name.
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentModule()
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mInit(C2_NO_INIT),
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mLibHandle(nullptr),
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              createFactory(nullptr),
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              destroyFactory(nullptr),
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mComponentFactory(nullptr) {
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Initializes a component module with a given library path. Must be called exactly once.
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param libPath[in] library path (or name)
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t init(std::string libPath);
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual ~ComponentModule() override;
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    protected:
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::recursive_mutex mLock; ///< lock protecting mTraits
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t mInit; ///< initialization result
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        void *mLibHandle; ///< loaded library handle
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loadable component module.
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo make this also work for enumerations
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentLoader {
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Load the component module.
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * This method simply returns the component module if it is already currently loaded, or
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * attempts to load it if it is not.
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *                    This will be nullptr on error.
5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded
5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module
5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            c2_status_t res = C2_OK;
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::lock_guard<std::mutex> lock(mMutex);
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<ComponentModule> localModule = mModule.lock();
5414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (localModule == nullptr) {
5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                localModule = std::make_shared<ComponentModule>();
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                res = localModule->init(mLibPath);
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (res == C2_OK) {
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mModule = localModule;
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *module = localModule;
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return res;
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates a component loader for a specific library path (or name).
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader(std::string libPath)
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mLibPath(libPath) {}
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mMutex; ///< mutex guarding the module
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::string mLibPath; ///< library path (or name)
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
564493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    struct Interface : public C2InterfaceHelper {
565493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
566493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
567493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        Interface(std::shared_ptr<C2ReflectorHelper> reflector)
568493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            : C2InterfaceHelper(reflector) {
569493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            setDerivedInstance(this);
570493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
571493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            struct Setter {
572493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                static C2R setIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
573493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().heapMask = ~0;
574493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().allocFlags = 0;
575493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().minAlignment = 0;
576493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    return C2R::Ok();
577493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
578493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            };
579493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
580493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            addParameter(
581493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                DefineParam(mIonUsageInfo, "ion-usage")
582493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withDefault(new C2StoreIonUsageInfo())
583493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withFields({
584493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, usage).flags({C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
585493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
586493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, heapMask).any(),
587493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, allocFlags).flags({}),
588493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, minAlignment).equalTo(0)
589493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                })
590493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withSetter(Setter::setIonUsage)
591493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .build());
592493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
593493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
594493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Retrieves the component loader for a component.
5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \return a non-ref-holding pointer to the component loader.
5994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
6004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_OK        the component loader has been successfully retrieved
6014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NO_MEMORY not enough memory to locate the component loader
6024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NOT_FOUND could not locate the component to be loaded
6034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
6044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      corrupted (this can happen if the name does not refer to an already
6054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      identified component but some components could not be loaded due to
6064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      bad library)
6074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_REFUSED   permission denied to find the component loader for the named component
6084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      (this can happen if the name does not refer to an already identified
6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      component but some components could not be loaded due to lack of
6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      permissions)
6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t findComponent(C2String name, ComponentLoader **loader);
6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::map<C2String, ComponentLoader> mComponents; ///< list of components
6159fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mReflector;
616493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    Interface mInterface;
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) {
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("loading dll");
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle == nullptr) {
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // could be access/symbol or simply not being there
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror());
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mInit = C2_CORRUPTED;
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        createFactory =
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory =
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mComponentFactory = createFactory();
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mComponentFactory == nullptr) {
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("could not create factory in %s", libPath.c_str());
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_NO_MEMORY;
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_OK;
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mInit;
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformComponentStore::ComponentModule::~ComponentModule() {
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (destroyFactory && mComponentFactory) {
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory(mComponentFactory);
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle) {
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("unloading dll");
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        dlclose(mLibHandle);
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2ComponentInterface*)> deleter) {
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createInterface(
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting interface
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete interface first
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2Component> *component,
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2Component*)> deleter) {
6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createComponent(
6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, component, [module, deleter](C2Component *p) mutable {
6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting component
6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete component first
6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_lock<std::recursive_mutex> lock(mLock);
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mTraits) {
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2ComponentInterface> intf;
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = createInterface(0, &intf);
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res != C2_OK) {
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("failed to create interface: %d", res);
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return nullptr;
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
7004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (traits) {
7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->name = intf->getName();
7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this from interface properly.
7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            bool encoder = (traits->name.find("encoder") != std::string::npos);
7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t mediaTypeIndex = encoder ? C2PortMimeConfig::output::PARAM_TYPE
7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    : C2PortMimeConfig::input::PARAM_TYPE;
7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> params;
7074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
7084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (res != C2_OK) {
7094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: %d", res);
7104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (params.size() != 1u) {
7134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
7144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2PortMimeConfig *mediaTypeConfig = (C2PortMimeConfig *)(params[0].get());
7174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mediaTypeConfig == nullptr) {
7184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query media type");
7194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->mediaType = mediaTypeConfig->m.value;
7224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this properly.
7234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->rank = 0x200;
724a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa
725a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            // TODO: define these values properly
726a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            bool decoder = (traits->name.find("decoder") != std::string::npos);
727a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            traits->kind =
728a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    decoder ? C2Component::KIND_DECODER :
729a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    encoder ? C2Component::KIND_ENCODER :
730a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    C2Component::KIND_OTHER;
731a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
732a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_AUDIO;
733a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
734a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_VIDEO;
735a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
736a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_IMAGE;
737a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else {
738a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_OTHER;
739a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            }
7404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
7414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mTraits = traits;
7434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mTraits;
7454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7479fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik KimC2PlatformComponentStore::C2PlatformComponentStore()
748493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    : mReflector(std::make_shared<C2ReflectorHelper>()),
749493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar      mInterface(mReflector) {
7504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: move this also into a .so so it can be updated
7515c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.decoder", "libstagefright_soft_c2avcdec.so");
7525c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.encoder", "libstagefright_soft_c2avcenc.so");
7535c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.decoder", "libstagefright_soft_c2aacdec.so");
7545c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.encoder", "libstagefright_soft_c2aacenc.so");
7555c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.decoder", "libstagefright_soft_c2amrnbdec.so");
7565c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.encoder", "libstagefright_soft_c2amrnbenc.so");
7575c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.decoder", "libstagefright_soft_c2amrwbdec.so");
7585c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.encoder", "libstagefright_soft_c2amrwbenc.so");
7595c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.hevc.decoder", "libstagefright_soft_c2hevcdec.so");
7605c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.alaw.decoder", "libstagefright_soft_c2g711alawdec.so");
7615c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.mlaw.decoder", "libstagefright_soft_c2g711mlawdec.so");
7625c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg2.decoder", "libstagefright_soft_c2mpeg2dec.so");
7635c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.decoder", "libstagefright_soft_c2h263dec.so");
7645c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.encoder", "libstagefright_soft_c2h263enc.so");
7655c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.decoder", "libstagefright_soft_c2mpeg4dec.so");
7665c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.encoder", "libstagefright_soft_c2mpeg4enc.so");
7675c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mp3.decoder", "libstagefright_soft_c2mp3dec.so");
7685c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vorbis.decoder", "libstagefright_soft_c2vorbisdec.so");
7695c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.opus.decoder", "libstagefright_soft_c2opusdec.so");
7705c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.decoder", "libstagefright_soft_c2vp8dec.so");
7715c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.decoder", "libstagefright_soft_c2vp9dec.so");
7725c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.encoder", "libstagefright_soft_c2vp8enc.so");
7735c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.encoder", "libstagefright_soft_c2vp9enc.so");
7745c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.raw.decoder", "libstagefright_soft_c2rawdec.so");
7755c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.decoder", "libstagefright_soft_c2flacdec.so");
7765c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.encoder", "libstagefright_soft_c2flacenc.so");
7775c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.gsm.decoder", "libstagefright_soft_c2gsmdec.so");
7784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::copyBuffer(
7814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
7824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)src;
7834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)dst;
7844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OMITTED;
7854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::query_sm(
7884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &stackParams,
7894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param::Index> &heapParamIndices,
7904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
791493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
7924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::config_sm(
7954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &params,
7964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
797493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.config(params, C2_MAY_BLOCK, failures);
7984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
8014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 500ms.
8024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<const C2Component::Traits>> list;
8034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (auto &it : mComponents) {
8044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader &loader = it.second;
8054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = loader.fetchModule(&module);
8074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
8094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (traits) {
8104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                list.push_back(traits);
8114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
8124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return list;
8154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) {
8184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = nullptr;
8194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto pos = mComponents.find(name);
8204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: check aliases
8214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (pos == mComponents.end()) {
8224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
8234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = &pos->second;
8254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
8264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createComponent(
8294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2Component> *const component) {
8304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
8324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createComponent(0, component);
8404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createInterface(
8464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
8474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
8494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createInterface(0, interface);
8574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedParams_nb(
8634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
864493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedParams(params);
8654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedValues_sm(
8684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2FieldSupportedValuesQuery> &fields) const {
869493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
8704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2String C2PlatformComponentStore::getName() const {
8734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return "android.componentStore.platform";
8744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
8779fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    return mReflector;
8784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
8814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
8824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2ComponentStore> platformStore;
8834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
8844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
8854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (store == nullptr) {
8864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        store = std::make_shared<C2PlatformComponentStore>();
8874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        platformStore = store;
8884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return store;
8904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
893