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>
272a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin#include <C2PlatformStorePluginLoader.h>
284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2PlatformSupport.h>
299fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim#include <util/C2InterfaceHelper.h>
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <dlfcn.h>
32493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar#include <unistd.h> // getpagesize
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <map>
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <memory>
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <mutex>
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
41493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar * Returns the preferred component store in this process to access its interface.
42493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar */
43493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore();
44493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
45493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar/**
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * The platform allocator store provides basic allocator-types for the framework based on ion and
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * gralloc. Allocators are not meant to be updatable.
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Provide allocator based on ashmem
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * \todo Make this allocator store extendable
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
55493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2PlatformAllocatorStoreImpl();
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t fetchAllocator(
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const override {
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override {
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return "android.allocator-store";
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
69493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    void setComponentStore(std::shared_ptr<C2ComponentStore> store);
70493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
71493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    ~C2PlatformAllocatorStoreImpl() override = default;
72493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton ion allocator
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchIonAllocator();
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /// returns a shared-singleton gralloc allocator
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
79493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
8038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    /// returns a shared-singleton bufferqueue supporting gralloc allocator
8138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
8238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
83493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    /// component store to use
84493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
85493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                                        // dependencies
86493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex _mComponentStoreReadLock; // must protect only read/write of _mComponentStore
87493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> _mComponentStore;
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    allocator->reset();
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: should we implement a generic registry for all, and use that?
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::ION:
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_LINEAR:
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchIonAllocator();
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2PlatformAllocatorStore::GRALLOC:
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2AllocatorStore::DEFAULT_GRAPHIC:
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *allocator = fetchGrallocAllocator();
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    case C2PlatformAllocatorStore::BUFFERQUEUE:
10938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        *allocator = fetchBufferQueueAllocator();
11038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        break;
11138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (*allocator == nullptr) {
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NO_MEMORY;
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
121493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
122493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
123493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::mutex gIonAllocatorMutex;
124493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::weak_ptr<C2AllocatorIon> gIonAllocator;
125493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
126493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid UseComponentStoreForIonAllocator(
127493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        const std::shared_ptr<C2AllocatorIon> allocator,
128493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> store) {
129493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2AllocatorIon::UsageMapperFn mapper;
130493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t minUsage = 0;
131493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    uint64_t maxUsage = C2MemoryUsage(C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE).expected;
132493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    size_t blockSize = getpagesize();
133493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
134493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // query min and max usage as well as block size via supported values
135493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    C2StoreIonUsageInfo usageInfo;
136493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::vector<C2FieldSupportedValuesQuery> query = {
137493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.usage)),
138493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        C2FieldSupportedValuesQuery::Possible(C2ParamField::Make(usageInfo, usageInfo.capacity)),
139493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
140493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    c2_status_t res = store->querySupportedValues_sm(query);
141493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (res == C2_OK) {
142493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[0].status == C2_OK) {
143493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[0].values;
144493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::FLAGS && !fsv.values.empty()) {
145493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                minUsage = fsv.values[0].u64;
146493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                maxUsage = 0;
147493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                for (C2Value::Primitive v : fsv.values) {
148493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    maxUsage |= v.u64;
149493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
150493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
151493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
152493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        if (query[1].status == C2_OK) {
153493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            const C2FieldSupportedValues &fsv = query[1].values;
154493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (fsv.type == C2FieldSupportedValues::RANGE && fsv.range.step.u32 > 0) {
155493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                blockSize = fsv.range.step.u32;
156493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
157493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
158493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
159493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        mapper = [store](C2MemoryUsage usage, size_t capacity,
160493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                         size_t *align, unsigned *heapMask, unsigned *flags) -> c2_status_t {
161493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (capacity > UINT32_MAX) {
162493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                return C2_BAD_VALUE;
163493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
164493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            C2StoreIonUsageInfo usageInfo = { usage.expected, capacity };
165493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::vector<std::unique_ptr<C2SettingResult>> failures; // TODO: remove
166493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            c2_status_t res = store->config_sm({&usageInfo}, &failures);
167493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            if (res == C2_OK) {
168493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *align = usageInfo.minAlignment;
169493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *heapMask = usageInfo.heapMask;
170493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                *flags = usageInfo.allocFlags;
171493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            }
172493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            return res;
173493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        };
174493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
175493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
176493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    allocator->setUsageMapper(mapper, minUsage, maxUsage, blockSize);
177493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
178493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
179493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
180493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
181493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid C2PlatformAllocatorStoreImpl::setComponentStore(std::shared_ptr<C2ComponentStore> store) {
182493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // technically this set lock is not needed, but is here for safety in case we add more
183493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // getter orders
184493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(_mComponentStoreSetLock);
185493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
186493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
187493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        _mComponentStore = store;
188493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
189493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator;
190493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
191493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
192493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocator = gIonAllocator.lock();
193493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
194493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocator) {
195493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, store);
196493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
197493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
198493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
200493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
201493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2AllocatorIon> allocator = gIonAllocator.lock();
2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
203493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2ComponentStore> componentStore;
204493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        {
205493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
206493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            componentStore = _mComponentStore;
207493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
2084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
209493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        UseComponentStoreForIonAllocator(allocator, componentStore);
210493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gIonAllocator = allocator;
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2Allocator> grallocAllocator;
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (allocator == nullptr) {
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        grallocAllocator = allocator;
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return allocator;
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
22738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Leestd::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchBufferQueueAllocator() {
22838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::mutex mutex;
22938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    static std::weak_ptr<C2Allocator> grallocAllocator;
23038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::lock_guard<std::mutex> lock(mutex);
23138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
23238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    if (allocator == nullptr) {
23338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        allocator = std::make_shared<C2AllocatorGralloc>(
23438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, true);
23538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        grallocAllocator = allocator;
23638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    }
23738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    return allocator;
23838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee}
23938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee
240493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarnamespace {
241493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPreferredComponentStoreMutex;
242493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
243493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
244493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::mutex gPlatformAllocatorStoreMutex;
245493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::weak_ptr<C2PlatformAllocatorStoreImpl> gPlatformAllocatorStore;
246493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
247493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
249493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
250493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> store = gPlatformAllocatorStore.lock();
251493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (store == nullptr) {
252493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store = std::make_shared<C2PlatformAllocatorStoreImpl>();
253493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        store->setComponentStore(GetPreferredCodec2ComponentStore());
254493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPlatformAllocatorStore = store;
255493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
256493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return store;
257493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
258493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
259493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarvoid SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> componentStore) {
260493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    static std::mutex mutex;
261493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(mutex); // don't interleve set-s
262493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
263493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update preferred store
264493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
265493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
266493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        gPreferredComponentStore = componentStore;
267493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
268493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
269493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    // update platform allocator's store as well if it is alive
270493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::shared_ptr<C2PlatformAllocatorStoreImpl> allocatorStore;
271493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    {
272493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
273493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore = gPlatformAllocatorStore.lock();
274493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
275493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    if (allocatorStore) {
276493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        allocatorStore->setComponentStore(componentStore);
277493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    }
278493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar}
279493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
280493e8165262315157bea75dcea642b30c916a2a7Lajos Molnarstd::shared_ptr<C2ComponentStore> GetPreferredCodec2ComponentStore() {
281493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
282493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return gPreferredComponentStore ? gPreferredComponentStore : GetCodec2PlatformComponentStore();
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
28539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leenamespace {
28639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
28739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeclass _C2BlockPoolCache {
28839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leepublic:
28939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
29039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
29139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t _createBlockPool(
2928060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
2938060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
2948060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t poolId,
29539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
29639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2AllocatorStore> allocatorStore =
29739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                GetCodec2PlatformAllocatorStore();
29839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        std::shared_ptr<C2Allocator> allocator;
29939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        c2_status_t res = C2_NOT_FOUND;
30039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
30139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        switch(allocatorId) {
30239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            case C2PlatformAllocatorStore::ION:
3034a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2AllocatorStore::DEFAULT_LINEAR:
30439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
30539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
30639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
307878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
30839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2PooledBlockPool>(
30939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
31039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
311878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3128060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
31339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
31439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
3154a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2PlatformAllocatorStore::GRALLOC:
3164a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            case C2AllocatorStore::DEFAULT_GRAPHIC:
3174a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                res = allocatorStore->fetchAllocator(
3184a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
3194a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                if (res == C2_OK) {
3204a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    std::shared_ptr<C2BlockPool> ptr =
3214a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        std::make_shared<C2PooledBlockPool>(allocator, poolId);
3224a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    *pool = ptr;
3234a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    mBlockPools[poolId] = ptr;
3244a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    mComponents[poolId] = component;
3254a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                }
3264a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                break;
32738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            case C2PlatformAllocatorStore::BUFFERQUEUE:
32839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                res = allocatorStore->fetchAllocator(
32938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                        C2PlatformAllocatorStore::BUFFERQUEUE, &allocator);
33039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                if (res == C2_OK) {
331878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::shared_ptr<C2BlockPool> ptr =
33239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                            std::make_shared<C2BufferQueueBlockPool>(
33339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                                    allocator, poolId);
33439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                    *pool = ptr;
335878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    mBlockPools[poolId] = ptr;
3368060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    mComponents[poolId] = component;
33739d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                }
33839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
33939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            default:
3402a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                // Try to create block pool from platform store plugins.
3412a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                std::shared_ptr<C2BlockPool> ptr;
3422a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                res = C2PlatformStorePluginLoader::GetInstance()->createBlockPool(
3432a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                        allocatorId, poolId, &ptr);
3442a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                if (res == C2_OK) {
3452a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                    *pool = ptr;
3462a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                    mBlockPools[poolId] = ptr;
3472a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                    mComponents[poolId] = component;
3482a7bdc84b59ab2f2e5674496db2705626095991dPin-chih Lin                }
34939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee                break;
35039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
35139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return res;
35239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
35339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
35439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    c2_status_t createBlockPool(
3558060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2PlatformAllocatorStore::id_t allocatorId,
3568060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3578060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
3588060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        return _createBlockPool(allocatorId, component, mBlockPoolSeqId++, pool);
35939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
36039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3618060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    bool getBlockPool(
3628060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            C2BlockPool::local_id_t blockPoolId,
3638060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<const C2Component> component,
3648060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            std::shared_ptr<C2BlockPool> *pool) {
36589eabf0d6b92d93eced043ce4abd2ac527c0374aPawin Vongmasa        // TODO: use one iterator for multiple blockpool type scalability.
3668060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        std::shared_ptr<C2BlockPool> ptr;
367878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        auto it = mBlockPools.find(blockPoolId);
368878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (it != mBlockPools.end()) {
369878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            ptr = it->second.lock();
3708060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            if (!ptr) {
371878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                mBlockPools.erase(it);
3728060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                mComponents.erase(blockPoolId);
3738060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee            } else {
3748060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                auto found = mComponents.find(blockPoolId);
3758060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                if (component == found->second.lock()) {
3768060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    *pool = ptr;
3778060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                    return true;
3788060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee                }
37939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            }
38039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
38139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        return false;
38239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
38339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
38439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leeprivate:
38539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    C2BlockPool::local_id_t mBlockPoolSeqId;
3868060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee
387878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
3888060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    std::map<C2BlockPool::local_id_t, std::weak_ptr<const C2Component>> mComponents;
38939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee};
39039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
39139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
39239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::make_unique<_C2BlockPoolCache>();
39339d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Leestatic std::mutex sBlockPoolCacheMutex;
39439d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
39539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee} // anynymous namespace
39639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
3974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t GetCodec2BlockPool(
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
40139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Allocator> allocator;
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = C2_NOT_FOUND;
4054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
40639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    if (id >= C2BlockPool::PLATFORM_START) {
4078060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        if (sBlockPoolCache->getBlockPool(id, component, pool)) {
40839d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee            return C2_OK;
40939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        }
41039d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    }
41139d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch (id) {
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_LINEAR:
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
4154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
4174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    case C2BlockPool::BASIC_GRAPHIC:
4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
42539d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    // TODO: remove this. this is temporary
42639d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    case C2BlockPool::PLATFORM_START:
4278060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee        res = sBlockPoolCache->_createBlockPool(
42838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                C2PlatformAllocatorStore::BUFFERQUEUE, component, id, pool);
42939d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee        break;
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    default:
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        break;
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t CreateCodec2BlockPool(
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlatformAllocatorStore::id_t allocatorId,
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component> component,
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2BlockPool> *pool) {
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    pool->reset();
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
44239d6e9366df0bd14dda1f97c9e6a43032dead1b0Sungtak Lee    std::lock_guard<std::mutex> lock(sBlockPoolCacheMutex);
4438060cb241e5091bc325599b0d609fd36360942e9Sungtak Lee    return sBlockPoolCache->createBlockPool(allocatorId, component, pool);
4444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PlatformComponentStore : public C2ComponentStore {
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual C2String getName() const override;
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedValues_sm(
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t querySupportedParams_nb(
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t query_sm(
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &stackParams,
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param::Index> &heapParamIndices,
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createInterface(
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t createComponent(
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2String name, std::shared_ptr<C2Component> *const component) override;
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t copyBuffer(
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual c2_status_t config_sm(
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<C2Param*> &params,
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2PlatformComponentStore();
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    virtual ~C2PlatformComponentStore() override = default;
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loaded component module.
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo provide a way to add traits to known components here to avoid loading the .so-s
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for listComponents
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentModule : public C2ComponentFactory,
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            public std::enable_shared_from_this<ComponentModule> {
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createComponent(
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2Component> *component,
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual c2_status_t createInterface(
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \returns the traits of the component in this module.
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<const C2Component::Traits> getTraits();
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates an uninitialized component module.
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param name[in]  component name.
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentModule()
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mInit(C2_NO_INIT),
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mLibHandle(nullptr),
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              createFactory(nullptr),
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              destroyFactory(nullptr),
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mComponentFactory(nullptr) {
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Initializes a component module with a given library path. Must be called exactly once.
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \note Only used by ComponentLoader.
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param libPath[in] library path (or name)
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t init(std::string libPath);
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        virtual ~ComponentModule() override;
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    protected:
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::recursive_mutex mLock; ///< lock protecting mTraits
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
5304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t mInit; ///< initialization result
5324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        void *mLibHandle; ///< loaded library handle
5344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
5354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
5364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
5374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * An object encapsulating a loadable component module.
5414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
5424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \todo make this also work for enumerations
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ComponentLoader {
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Load the component module.
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * This method simply returns the component module if it is already currently loaded, or
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * attempts to load it if it is not.
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *                    This will be nullptr on error.
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         *
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_OK        the component module has been successfully loaded
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NO_MEMORY not enough memory to loading the component module
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_NOT_FOUND could not locate the component module
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_CORRUPTED the component module could not be loaded
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * \retval C2_REFUSED   permission denied to load the component module
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            c2_status_t res = C2_OK;
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::lock_guard<std::mutex> lock(mMutex);
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<ComponentModule> localModule = mModule.lock();
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (localModule == nullptr) {
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                localModule = std::make_shared<ComponentModule>();
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                res = localModule->init(mLibPath);
5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (res == C2_OK) {
5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mModule = localModule;
5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *module = localModule;
5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return res;
5734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /**
5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         * Creates a component loader for a specific library path (or name).
5774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim         */
5784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader(std::string libPath)
5794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mLibPath(libPath) {}
5804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
5824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mMutex; ///< mutex guarding the module
5834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
5844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::string mLibPath; ///< library path (or name)
5854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
587493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    struct Interface : public C2InterfaceHelper {
588493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
589493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
590493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        Interface(std::shared_ptr<C2ReflectorHelper> reflector)
591493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            : C2InterfaceHelper(reflector) {
592493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            setDerivedInstance(this);
593493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
594493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            struct Setter {
595493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                static C2R setIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
596493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().heapMask = ~0;
597493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().allocFlags = 0;
598493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    me.set().minAlignment = 0;
599493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    return C2R::Ok();
600493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                }
601493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            };
602493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
603493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar            addParameter(
604493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                DefineParam(mIonUsageInfo, "ion-usage")
605493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withDefault(new C2StoreIonUsageInfo())
606493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withFields({
607493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, usage).flags({C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
608493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
609493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, heapMask).any(),
610493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, allocFlags).flags({}),
611493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                    C2F(mIonUsageInfo, minAlignment).equalTo(0)
612493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                })
613493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .withSetter(Setter::setIonUsage)
614493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar                .build());
615493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar        }
616493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    };
617493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Retrieves the component loader for a component.
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \return a non-ref-holding pointer to the component loader.
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_OK        the component loader has been successfully retrieved
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NO_MEMORY not enough memory to locate the component loader
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_NOT_FOUND could not locate the component to be loaded
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      corrupted (this can happen if the name does not refer to an already
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      identified component but some components could not be loaded due to
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      bad library)
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * \retval C2_REFUSED   permission denied to find the component loader for the named component
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      (this can happen if the name does not refer to an already identified
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      component but some components could not be loaded due to lack of
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *                      permissions)
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t findComponent(C2String name, ComponentLoader **loader);
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::map<C2String, ComponentLoader> mComponents; ///< list of components
6389fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    std::shared_ptr<C2ReflectorHelper> mReflector;
639493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    Interface mInterface;
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) {
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("loading dll");
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle == nullptr) {
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // could be access/symbol or simply not being there
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror());
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mInit = C2_CORRUPTED;
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        createFactory =
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory =
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mComponentFactory = createFactory();
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mComponentFactory == nullptr) {
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("could not create factory in %s", libPath.c_str());
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_NO_MEMORY;
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mInit = C2_OK;
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mInit;
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PlatformComponentStore::ComponentModule::~ComponentModule() {
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ALOGV("in %s", __func__);
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (destroyFactory && mComponentFactory) {
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        destroyFactory(mComponentFactory);
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLibHandle) {
6734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALOGV("unloading dll");
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        dlclose(mLibHandle);
6754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
6794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
6804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2ComponentInterface*)> deleter) {
6814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
6824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
6834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
6844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
6864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createInterface(
6874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting interface
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete interface first
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_node_id_t id, std::shared_ptr<C2Component> *component,
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::function<void(::C2Component*)> deleter) {
6984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
6994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mInit != C2_OK) {
7004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mInit;
7014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<ComponentModule> module = shared_from_this();
7034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = mComponentFactory->createComponent(
7044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            id, component, [module, deleter](C2Component *p) mutable {
7054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // capture module so that we ensure we still have it while deleting component
7064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                deleter(p); // delete component first
7074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                module.reset(); // remove module ref (not technically needed)
7084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    });
7094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
7104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
7134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_lock<std::recursive_mutex> lock(mLock);
7144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mTraits) {
7154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2ComponentInterface> intf;
7164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = createInterface(0, &intf);
7174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res != C2_OK) {
7184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            ALOGD("failed to create interface: %d", res);
7194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return nullptr;
7204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
7214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
7234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (traits) {
7244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->name = intf->getName();
7254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this from interface properly.
7264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            bool encoder = (traits->name.find("encoder") != std::string::npos);
7274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t mediaTypeIndex = encoder ? C2PortMimeConfig::output::PARAM_TYPE
7284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    : C2PortMimeConfig::input::PARAM_TYPE;
7294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::vector<std::unique_ptr<C2Param>> params;
7304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
7314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (res != C2_OK) {
7324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: %d", res);
7334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (params.size() != 1u) {
7364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
7374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2PortMimeConfig *mediaTypeConfig = (C2PortMimeConfig *)(params[0].get());
7404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mediaTypeConfig == nullptr) {
7414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                ALOGD("failed to query media type");
7424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return nullptr;
7434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
7444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->mediaType = mediaTypeConfig->m.value;
7454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get this properly.
7464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            traits->rank = 0x200;
747a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa
748a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            // TODO: define these values properly
749a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            bool decoder = (traits->name.find("decoder") != std::string::npos);
750a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            traits->kind =
751a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    decoder ? C2Component::KIND_DECODER :
752a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    encoder ? C2Component::KIND_ENCODER :
753a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                    C2Component::KIND_OTHER;
754a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
755a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_AUDIO;
756a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
757a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_VIDEO;
758a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
759a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_IMAGE;
760a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            } else {
761a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa                traits->domain = C2Component::DOMAIN_OTHER;
762a165b1a2ce351042803e7150ce425e589c89a08ePawin Vongmasa            }
7634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
7644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mTraits = traits;
7664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mTraits;
7684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7709fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik KimC2PlatformComponentStore::C2PlatformComponentStore()
771493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    : mReflector(std::make_shared<C2ReflectorHelper>()),
772493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar      mInterface(mReflector) {
7734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: move this also into a .so so it can be updated
7745c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.decoder", "libstagefright_soft_c2avcdec.so");
7755c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.avc.encoder", "libstagefright_soft_c2avcenc.so");
7765c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.decoder", "libstagefright_soft_c2aacdec.so");
7775c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.aac.encoder", "libstagefright_soft_c2aacenc.so");
7785c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.decoder", "libstagefright_soft_c2amrnbdec.so");
7795c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrnb.encoder", "libstagefright_soft_c2amrnbenc.so");
7805c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.decoder", "libstagefright_soft_c2amrwbdec.so");
7815c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.amrwb.encoder", "libstagefright_soft_c2amrwbenc.so");
7825c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.hevc.decoder", "libstagefright_soft_c2hevcdec.so");
7835c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.alaw.decoder", "libstagefright_soft_c2g711alawdec.so");
7845c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.g711.mlaw.decoder", "libstagefright_soft_c2g711mlawdec.so");
7855c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg2.decoder", "libstagefright_soft_c2mpeg2dec.so");
7865c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.decoder", "libstagefright_soft_c2h263dec.so");
7875c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.h263.encoder", "libstagefright_soft_c2h263enc.so");
7885c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.decoder", "libstagefright_soft_c2mpeg4dec.so");
7895c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mpeg4.encoder", "libstagefright_soft_c2mpeg4enc.so");
7905c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.mp3.decoder", "libstagefright_soft_c2mp3dec.so");
7915c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vorbis.decoder", "libstagefright_soft_c2vorbisdec.so");
7925c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.opus.decoder", "libstagefright_soft_c2opusdec.so");
7935c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.decoder", "libstagefright_soft_c2vp8dec.so");
7945c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.decoder", "libstagefright_soft_c2vp9dec.so");
7955c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp8.encoder", "libstagefright_soft_c2vp8enc.so");
7965c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.vp9.encoder", "libstagefright_soft_c2vp9enc.so");
7975c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.raw.decoder", "libstagefright_soft_c2rawdec.so");
7985c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.decoder", "libstagefright_soft_c2flacdec.so");
7995c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.flac.encoder", "libstagefright_soft_c2flacenc.so");
8005c2c3d46fc95a4e08dbd7a7a3304e389d85faa86Lajos Molnar    mComponents.emplace("c2.android.gsm.decoder", "libstagefright_soft_c2gsmdec.so");
801644ade33117e336116ec97fca4c12d8245c12676Rakesh Kumar    mComponents.emplace("c2.android.xaac.decoder", "libstagefright_soft_c2xaacdec.so");
8024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::copyBuffer(
8054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
8064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)src;
8074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    (void)dst;
8084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OMITTED;
8094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::query_sm(
8124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &stackParams,
8134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param::Index> &heapParamIndices,
8144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
815493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
8164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::config_sm(
8194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<C2Param*> &params,
8204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
821493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.config(params, C2_MAY_BLOCK, failures);
8224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
8254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 500ms.
8264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<const C2Component::Traits>> list;
8274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (auto &it : mComponents) {
8284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ComponentLoader &loader = it.second;
8294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t res = loader.fetchModule(&module);
8314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
8334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (traits) {
8344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                list.push_back(traits);
8354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
8364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return list;
8394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) {
8424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = nullptr;
8434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    auto pos = mComponents.find(name);
8444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: check aliases
8454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (pos == mComponents.end()) {
8464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_NOT_FOUND;
8474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *loader = &pos->second;
8494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
8504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createComponent(
8534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2Component> *const component) {
8544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    component->reset();
8564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createComponent(0, component);
8644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::createInterface(
8704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
8714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // This method SHALL return within 100ms.
8724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    interface->reset();
8734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ComponentLoader *loader;
8744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t res = findComponent(name, &loader);
8754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (res == C2_OK) {
8764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ComponentModule> module;
8774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        res = loader->fetchModule(&module);
8784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (res == C2_OK) {
8794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: get a unique node ID
8804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            res = module->createInterface(0, interface);
8814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return res;
8844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedParams_nb(
8874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
888493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedParams(params);
8894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PlatformComponentStore::querySupportedValues_sm(
8924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<C2FieldSupportedValuesQuery> &fields) const {
893493e8165262315157bea75dcea642b30c916a2a7Lajos Molnar    return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
8944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2String C2PlatformComponentStore::getName() const {
8974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return "android.componentStore.platform";
8984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
8994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
9019fca24013957d2dfe99b4291f9f9297f720c7fa8Wonsik Kim    return mReflector;
9024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
9054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::mutex mutex;
9064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static std::weak_ptr<C2ComponentStore> platformStore;
9074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mutex);
9084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
9094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (store == nullptr) {
9104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        store = std::make_shared<C2PlatformComponentStore>();
9114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        platformStore = store;
9124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
9134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return store;
9144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim} // namespace android
917