14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2016 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
174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim//#define LOG_NDEBUG 0
184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#define LOG_TAG "C2Buffer"
194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <utils/Log.h>
204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <list>
224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <map>
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <mutex>
244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
25878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee#include <C2AllocatorIon.h>
26878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee#include <C2AllocatorGralloc.h>
274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2BufferPriv.h>
284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <C2BlockInternal.h>
296c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee#include <bufferpool/ClientManager.h>
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace {
324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
33878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leeusing android::C2AllocatorGralloc;
34878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leeusing android::C2AllocatorIon;
35878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leeusing android::hardware::media::bufferpool::BufferPoolData;
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimusing android::hardware::media::bufferpool::V1_0::ResultStatus;
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimusing android::hardware::media::bufferpool::V1_0::implementation::BufferPoolAllocation;
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimusing android::hardware::media::bufferpool::V1_0::implementation::BufferPoolAllocator;
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimusing android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimusing android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
4138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Leeusing android::hardware::media::bufferpool::V1_0::implementation::INVALID_CONNECTIONID;
424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// This anonymous namespace contains the helper classes that allow our implementation to create
444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// block/buffer objects.
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim//
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// Inherit from the parent, share with the friend.
474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass ReadViewBuddy : public C2ReadView {
484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2ReadView::C2ReadView;
494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2ConstLinearBlock;
504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass WriteViewBuddy : public C2WriteView {
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2WriteView::C2WriteView;
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2LinearBlock;
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass ConstLinearBlockBuddy : public C2ConstLinearBlock {
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2ConstLinearBlock::C2ConstLinearBlock;
594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2LinearBlock;
604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass LinearBlockBuddy : public C2LinearBlock {
634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2LinearBlock::C2LinearBlock;
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2BasicLinearBlockPool;
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass AcquirableReadViewBuddy : public C2Acquirable<C2ReadView> {
684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2Acquirable::C2Acquirable;
694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2ConstLinearBlock;
704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass AcquirableWriteViewBuddy : public C2Acquirable<C2WriteView> {
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2Acquirable::C2Acquirable;
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2LinearBlock;
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass GraphicViewBuddy : public C2GraphicView {
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2GraphicView::C2GraphicView;
794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2ConstGraphicBlock;
804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2GraphicBlock;
814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass AcquirableConstGraphicViewBuddy : public C2Acquirable<const C2GraphicView> {
844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2Acquirable::C2Acquirable;
854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2ConstGraphicBlock;
864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass AcquirableGraphicViewBuddy : public C2Acquirable<C2GraphicView> {
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2Acquirable::C2Acquirable;
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2GraphicBlock;
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass ConstGraphicBlockBuddy : public C2ConstGraphicBlock {
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2ConstGraphicBlock::C2ConstGraphicBlock;
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2GraphicBlock;
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass GraphicBlockBuddy : public C2GraphicBlock {
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2GraphicBlock::C2GraphicBlock;
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2BasicGraphicBlockPool;
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass BufferDataBuddy : public C2BufferData {
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using C2BufferData::C2BufferData;
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    friend class ::C2Buffer;
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace
1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* ========================================== 1D BLOCK ========================================= */
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * This class is the base class for all 1D block and view implementations.
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
1154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * This is basically just a placeholder for the underlying 1D allocation and the range of the
1164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * alloted portion to this block. There is also a placeholder for a blockpool data.
1174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
1184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2_HIDE _C2Block1DImpl : public _C2LinearRangeAspect {
1194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
1204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2Block1DImpl(const std::shared_ptr<C2LinearAllocation> &alloc,
1214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
1224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            size_t offset = 0, size_t size = ~(size_t)0)
1234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2LinearRangeAspect(alloc.get(), offset, size),
1244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mAllocation(alloc),
1254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mPoolData(poolData) { }
1264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2Block1DImpl(const _C2Block1DImpl &other, size_t offset = 0, size_t size = ~(size_t)0)
1284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2LinearRangeAspect(&other, offset, size),
1294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mAllocation(other.mAllocation),
1304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mPoolData(other.mPoolData) { }
1314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1322cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa    /** returns pool data  */
1332cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa    std::shared_ptr<_C2BlockPoolData> poolData() const {
1344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mPoolData;
1354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /** returns native handle */
1384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const C2Handle *handle() const {
1394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation ? mAllocation->handle() : nullptr;
1404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /** returns the allocator's ID */
1434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2Allocator::id_t getAllocatorId() const {
1444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
1454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
1464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2LinearAllocation> getAllocation() const {
1494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation;
1504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
1534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2LinearAllocation> mAllocation;
1544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2BlockPoolData> mPoolData;
1554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
1584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * This class contains the mapped data pointer, and the potential error.
1594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
1604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * range is the mapped range of the underlying allocation (which is part of the allotted
1614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * range).
1624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
1634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2_HIDE _C2MappedBlock1DImpl : public _C2Block1DImpl {
1644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
1654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2MappedBlock1DImpl(const _C2Block1DImpl &block, uint8_t *data,
1664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                         size_t offset = 0, size_t size = ~(size_t)0)
1674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2Block1DImpl(block, offset, size), mData(data), mError(C2_OK) { }
1684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2MappedBlock1DImpl(c2_status_t error)
1704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2Block1DImpl(nullptr), mData(nullptr), mError(error) {
1714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // CHECK(error != C2_OK);
1724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const uint8_t *data() const {
1754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mData;
1764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint8_t *data() {
1794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mData;
1804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t error() const {
1834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mError;
1844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
1874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint8_t *mData;
1884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t mError;
1894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
1924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Block implementation.
1934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
1944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2Block1D::Impl : public _C2Block1DImpl {
1954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2Block1DImpl::_C2Block1DImpl;
1964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst C2Handle *C2Block1D::handle() const {
1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->handle();
2004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Allocator::id_t C2Block1D::getAllocatorId() const {
2034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->getAllocatorId();
2044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
2054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Block1D::C2Block1D(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
2074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // always clamp subrange to parent (impl) range for safety
2084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2LinearRangeAspect(impl.get(), range.offset(), range.size()), mImpl(impl) {
2094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Read view implementation.
2134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
2144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * range of Impl is the mapped range of the underlying allocation (which is part of the allotted
2154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * range). range of View is 0 to capacity() (not represented as an actual range). This maps to a
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * subrange of Impl range starting at mImpl->offset() + _mOffset.
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2ReadView::Impl : public _C2MappedBlock1DImpl {
2194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ReadView::C2ReadView(std::shared_ptr<Impl> impl, uint32_t offset, uint32_t size)
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2LinearCapacityAspect(C2LinearCapacity(impl->size()).range(offset, size).size()),
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      mImpl(impl),
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim      mOffset(C2LinearCapacity(impl->size()).range(offset, size).offset()) { }
2264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ReadView::C2ReadView(c2_status_t error)
2284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2LinearCapacityAspect(0u), mImpl(std::make_shared<Impl>(error)), mOffset(0u) {
2294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // CHECK(error != C2_OK);
2304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst uint8_t *C2ReadView::data() const {
2334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->error() ? nullptr : mImpl->data() + mOffset;
2344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2ReadView::error() const {
2374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->error();
2384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ReadView C2ReadView::subView(size_t offset, size_t size) const {
2414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2LinearRange subRange(*this, offset, size);
2424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2ReadView(mImpl, mOffset + subRange.offset(), subRange.size());
2434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
2464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Write view implementation.
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2WriteView::Impl : public _C2MappedBlock1DImpl {
2494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
2504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
2514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2WriteView::C2WriteView(std::shared_ptr<Impl> impl)
2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// UGLY: _C2LinearRangeAspect requires a bona-fide object for capacity to prevent spoofing, so
2544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// this is what we have to do.
2554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TODO: use childRange
2564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2EditableLinearRangeAspect(std::make_unique<C2LinearCapacity>(impl->size()).get()), mImpl(impl) { }
2574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2WriteView::C2WriteView(c2_status_t error)
2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2EditableLinearRangeAspect(nullptr), mImpl(std::make_shared<Impl>(error)) {}
2604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimuint8_t *C2WriteView::base() { return mImpl->data(); }
2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimuint8_t *C2WriteView::data() { return mImpl->data() + offset(); }
2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2WriteView::error() const { return mImpl->error(); }
2664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
2684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Const linear block implementation.
2694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
2704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstLinearBlock::C2ConstLinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range, C2Fence fence)
2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : C2Block1D(impl, range), mFence(fence) { }
2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Acquirable<C2ReadView> C2ConstLinearBlock::map() const {
2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void *base = nullptr;
2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint32_t len = size();
2764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t error = mImpl->getAllocation()->map(
2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            offset(), len, { C2MemoryUsage::CPU_READ, 0 }, nullptr, &base);
2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: wait on fence
2794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (error == C2_OK) {
2804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<ReadViewBuddy::Impl> rvi = std::shared_ptr<ReadViewBuddy::Impl>(
2814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                new ReadViewBuddy::Impl(*mImpl, (uint8_t *)base, offset(), len),
2824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [base, len](ReadViewBuddy::Impl *i) {
2834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    (void)i->getAllocation()->unmap(base, len, nullptr);
2844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    delete i;
2854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        });
2864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(rvi, 0, len));
2874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
2884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(error));
2894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstLinearBlock C2ConstLinearBlock::subBlock(size_t offset_, size_t size_) const {
2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2LinearRange subRange(*mImpl, offset_, size_);
2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2ConstLinearBlock(mImpl, subRange, mFence);
2954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Linear block implementation.
2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2LinearBlock::C2LinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : C2Block1D(impl, range) { }
3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Acquirable<C2WriteView> C2LinearBlock::map() {
3044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void *base = nullptr;
3054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint32_t len = size();
3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t error = mImpl->getAllocation()->map(
3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            offset(), len, { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }, nullptr, &base);
3084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: wait on fence
3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (error == C2_OK) {
3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<WriteViewBuddy::Impl> rvi = std::shared_ptr<WriteViewBuddy::Impl>(
3114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                new WriteViewBuddy::Impl(*mImpl, (uint8_t *)base, 0, len),
3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [base, len](WriteViewBuddy::Impl *i) {
3134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    (void)i->getAllocation()->unmap(base, len, nullptr);
3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    delete i;
3154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        });
3164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(rvi));
3174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
3184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(error));
3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstLinearBlock C2LinearBlock::share(size_t offset_, size_t size_, C2Fence fence) {
3234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ConstLinearBlockBuddy(mImpl, C2LinearRange(*this, offset_, size_), fence);
3244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2BasicLinearBlockPool::C2BasicLinearBlockPool(
3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2Allocator> &allocator)
3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  : mAllocator(allocator) { }
3294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2BasicLinearBlockPool::fetchLinearBlock(
3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t capacity,
3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2MemoryUsage usage,
3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    block->reset();
3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2LinearAllocation> alloc;
3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t err = mAllocator->newLinearAllocation(capacity, usage, &alloc);
3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (err != C2_OK) {
3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return err;
3404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *block = _C2BlockFactory::CreateLinearBlock(alloc);
3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
347878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leestruct C2_HIDE C2PooledBlockPoolData : _C2BlockPoolData {
348878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
34938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    virtual type_t getType() const override {
350878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        return TYPE_BUFFERPOOL;
351878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
352878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
353878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    void getBufferPoolData(std::shared_ptr<BufferPoolData> *data) const {
354878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        *data = mData;
355878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
356878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
357878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    C2PooledBlockPoolData(const std::shared_ptr<BufferPoolData> &data) : mData(data) {}
358878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
359878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    virtual ~C2PooledBlockPoolData() override {}
360878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
361878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leeprivate:
362878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::shared_ptr<BufferPoolData> mData;
363878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee};
364878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
365878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leebool _C2BlockFactory::GetBufferPoolData(
366878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const std::shared_ptr<const _C2BlockPoolData> &data,
367878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        std::shared_ptr<BufferPoolData> *bufferPoolData) {
368878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    if (data && data->getType() == _C2BlockPoolData::TYPE_BUFFERPOOL) {
369878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const std::shared_ptr<const C2PooledBlockPoolData> poolData =
370878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                std::static_pointer_cast<const C2PooledBlockPoolData>(data);
371878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        poolData->getBufferPoolData(bufferPoolData);
372878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        return true;
373878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
374878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return false;
375878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee}
376878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
3784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2LinearAllocation> &alloc,
3794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<_C2BlockPoolData> &data, size_t offset, size_t size) {
3804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Block1D::Impl> impl =
3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::make_shared<C2Block1D::Impl>(alloc, data, offset, size);
3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::shared_ptr<C2LinearBlock>(new C2LinearBlock(impl, *impl));
3834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3852cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasastd::shared_ptr<_C2BlockPoolData> _C2BlockFactory::GetLinearBlockPoolData(
386878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const C2Block1D &block) {
387878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    if (block.mImpl) {
388878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        return block.mImpl->poolData();
389878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
390878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return nullptr;
391878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee}
392878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
393878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leestd::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
394878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const C2Handle *handle) {
395878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    // TODO: get proper allocator? and mutex?
396878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
397878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
398878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::shared_ptr<C2LinearAllocation> alloc;
399878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    if (C2AllocatorIon::isValid(handle)) {
400878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc);
401878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (err == C2_OK) {
402878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(alloc);
403878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            return block;
404878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        }
405878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
406878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return nullptr;
407878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee}
408878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
409878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leestd::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
41038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        const C2Handle *cHandle, const std::shared_ptr<BufferPoolData> &data) {
411878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    // TODO: get proper allocator? and mutex?
412878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
413878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
414878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::shared_ptr<C2LinearAllocation> alloc;
41538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    if (C2AllocatorIon::isValid(cHandle)) {
41638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t *handle = native_handle_clone(cHandle);
417878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (handle) {
418878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc);
419878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            const std::shared_ptr<C2PooledBlockPoolData> poolData =
420878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::make_shared<C2PooledBlockPoolData>(data);
421878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            if (err == C2_OK && poolData) {
422878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                // TODO: config params?
423878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                std::shared_ptr<C2LinearBlock> block =
424878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                        _C2BlockFactory::CreateLinearBlock(alloc, poolData);
425878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                return block;
426878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            }
427878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        }
428878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
429878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return nullptr;
430878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee};
431878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Wrapped C2Allocator which is injected to buffer pool on behalf of
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * C2BlockPool.
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass _C2BufferPoolAllocator : public BufferPoolAllocator {
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2BufferPoolAllocator(const std::shared_ptr<C2Allocator> &allocator)
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mAllocator(allocator) {}
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ~_C2BufferPoolAllocator() override {}
4424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus allocate(const std::vector<uint8_t> &params,
444da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                          std::shared_ptr<BufferPoolAllocation> *alloc,
445da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                          size_t *allocSize) override;
4464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool compatible(const std::vector<uint8_t> &newParams,
4484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    const std::vector<uint8_t> &oldParams) override;
4494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // Methods for codec2 component (C2BlockPool).
4514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Transforms linear allocation parameters for C2Allocator to parameters
4534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for buffer pool.
4544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param capacity      size of linear allocation
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param usage         memory usage pattern for linear allocation
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param params        allocation parameters for buffer pool
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void getLinearParams(uint32_t capacity, C2MemoryUsage usage,
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                         std::vector<uint8_t> *params);
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Transforms graphic allocation parameters for C2Allocator to parameters
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * for buffer pool.
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param width         width of graphic allocation
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param height        height of graphic allocation
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param format        color format of graphic allocation
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * @param params        allocation parameter for buffer pool
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void getGraphicParams(uint32_t width, uint32_t height,
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                          uint32_t format, C2MemoryUsage usage,
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                          std::vector<uint8_t> *params);
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Transforms an existing native handle to an C2LinearAllcation.
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Wrapper to C2Allocator#priorLinearAllocation
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t priorLinearAllocation(
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const C2Handle *handle,
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2LinearAllocation> *c2Allocation);
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Transforms an existing native handle to an C2GraphicAllcation.
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Wrapper to C2Allocator#priorGraphicAllocation
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t priorGraphicAllocation(
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const C2Handle *handle,
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2GraphicAllocation> *c2Allocation);
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    static constexpr int kMaxIntParams = 5; // large enough number;
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    enum AllocType : uint8_t {
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALLOC_NONE = 0,
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALLOC_LINEAR,
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ALLOC_GRAPHIC,
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    union AllocParams {
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        struct {
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            AllocType allocType;
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            C2MemoryUsage usage;
5054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t params[kMaxIntParams];
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } data;
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint8_t array[0];
5084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        AllocParams() : data{ALLOC_NONE, {0, 0}, {0}} {}
5104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        AllocParams(C2MemoryUsage usage, uint32_t capacity)
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : data{ALLOC_LINEAR, usage, {[0] = capacity}} {}
5124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        AllocParams(
5134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                C2MemoryUsage usage,
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                uint32_t width, uint32_t height, uint32_t format)
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                : data{ALLOC_GRAPHIC, usage, {width, height, format}} {}
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
5174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::shared_ptr<C2Allocator> mAllocator;
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct LinearAllocationDtor {
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    LinearAllocationDtor(const std::shared_ptr<C2LinearAllocation> &alloc)
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mAllocation(alloc) {}
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
5264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::shared_ptr<C2LinearAllocation> mAllocation;
5284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
5294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5304a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasastruct GraphicAllocationDtor {
5314a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    GraphicAllocationDtor(const std::shared_ptr<C2GraphicAllocation> &alloc)
5324a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        : mAllocation(alloc) {}
5334a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa
5344a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
5354a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa
5364a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    const std::shared_ptr<C2GraphicAllocation> mAllocation;
5374a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa};
5384a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa
5394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus _C2BufferPoolAllocator::allocate(
5404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t>  &params,
541da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        std::shared_ptr<BufferPoolAllocation> *alloc,
542da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        size_t *allocSize) {
5434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    AllocParams c2Params;
5444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    memcpy(&c2Params, params.data(), std::min(sizeof(AllocParams), params.size()));
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t status = C2_BAD_VALUE;
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    switch(c2Params.data.allocType) {
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        case ALLOC_NONE:
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            break;
5494a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        case ALLOC_LINEAR: {
5504a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            std::shared_ptr<C2LinearAllocation> c2Linear;
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            status = mAllocator->newLinearAllocation(
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    c2Params.data.params[0], c2Params.data.usage, &c2Linear);
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (status == C2_OK && c2Linear) {
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                BufferPoolAllocation *ptr = new BufferPoolAllocation(c2Linear->handle());
5554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (ptr) {
5564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    *alloc = std::shared_ptr<BufferPoolAllocation>(
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            ptr, LinearAllocationDtor(c2Linear));
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (*alloc) {
559da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                        *allocSize = (size_t)c2Params.data.params[0];
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        return ResultStatus::OK;
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    delete ptr;
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return ResultStatus::NO_MEMORY;
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            break;
5674a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        }
5684a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        case ALLOC_GRAPHIC: {
5694a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            std::shared_ptr<C2GraphicAllocation> c2Graphic;
5704a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            status = mAllocator->newGraphicAllocation(
5714a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    c2Params.data.params[0],
5724a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    c2Params.data.params[1],
5734a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    c2Params.data.params[2],
5744a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    c2Params.data.usage, &c2Graphic);
5754a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            if (status == C2_OK && c2Graphic) {
5764a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                BufferPoolAllocation *ptr = new BufferPoolAllocation(c2Graphic->handle());
5774a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                if (ptr) {
5784a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    *alloc = std::shared_ptr<BufferPoolAllocation>(
5794a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                            ptr, GraphicAllocationDtor(c2Graphic));
5804a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    if (*alloc) {
581da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                        *allocSize = c2Params.data.params[0] * c2Params.data.params[1];
5824a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        return ResultStatus::OK;
5834a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    }
5844a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    delete ptr;
5854a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                }
5864a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                return ResultStatus::NO_MEMORY;
5874a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            }
5884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            break;
5894a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        }
5904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        default:
5914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            break;
5924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
5944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool _C2BufferPoolAllocator::compatible(
5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t>  &newParams,
5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t>  &oldParams) {
5998466db50f14989d9413ef13a7da97ca987480194Sungtak Lee    AllocParams newAlloc;
6008466db50f14989d9413ef13a7da97ca987480194Sungtak Lee    AllocParams oldAlloc;
6018466db50f14989d9413ef13a7da97ca987480194Sungtak Lee    memcpy(&newAlloc, newParams.data(), std::min(sizeof(AllocParams), newParams.size()));
6028466db50f14989d9413ef13a7da97ca987480194Sungtak Lee    memcpy(&oldAlloc, oldParams.data(), std::min(sizeof(AllocParams), oldParams.size()));
6034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: support not exact matching. e.g) newCapacity < oldCapacity
6058466db50f14989d9413ef13a7da97ca987480194Sungtak Lee    if (newAlloc.data.allocType == oldAlloc.data.allocType &&
6068466db50f14989d9413ef13a7da97ca987480194Sungtak Lee            newAlloc.data.usage.expected == oldAlloc.data.usage.expected) {
6078466db50f14989d9413ef13a7da97ca987480194Sungtak Lee        for (int i = 0; i < kMaxIntParams; ++i) {
6088466db50f14989d9413ef13a7da97ca987480194Sungtak Lee            if (newAlloc.data.params[i] != oldAlloc.data.params[i]) {
6094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return false;
6104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
6114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return true;
6134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return false;
6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid _C2BufferPoolAllocator::getLinearParams(
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t capacity, C2MemoryUsage usage, std::vector<uint8_t> *params) {
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    AllocParams c2Params(usage, capacity);
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid _C2BufferPoolAllocator::getGraphicParams(
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<uint8_t> *params) {
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    AllocParams c2Params(usage, width, height, format);
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t _C2BufferPoolAllocator::priorLinearAllocation(
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const C2Handle *handle,
6324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2LinearAllocation> *c2Allocation) {
6334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mAllocator->priorLinearAllocation(handle, c2Allocation);
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t _C2BufferPoolAllocator::priorGraphicAllocation(
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const C2Handle *handle,
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicAllocation> *c2Allocation) {
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mAllocator->priorGraphicAllocation(handle, c2Allocation);
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2PooledBlockPool::Impl {
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
6444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Impl(const std::shared_ptr<C2Allocator> &allocator)
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mInit(C2_OK),
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mBufferPoolManager(ClientManager::getInstance()),
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              mAllocator(std::make_shared<_C2BufferPoolAllocator>(allocator)) {
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mAllocator && mBufferPoolManager) {
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mBufferPoolManager->create(
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mAllocator, &mConnectionId) == ResultStatus::OK) {
6514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return;
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mInit = C2_NO_INIT;
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ~Impl() {
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mInit == C2_OK) {
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mBufferPoolManager->close(mConnectionId);
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t fetchLinearBlock(
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            uint32_t capacity, C2MemoryUsage usage,
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        block->reset();
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mInit != C2_OK) {
6684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return mInit;
6694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<uint8_t> params;
6714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mAllocator->getLinearParams(capacity, usage, &params);
672878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        std::shared_ptr<BufferPoolData> bufferPoolData;
67338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t *cHandle = nullptr;
6744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ResultStatus status = mBufferPoolManager->allocate(
67538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                mConnectionId, params, &cHandle, &bufferPoolData);
6764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (status == ResultStatus::OK) {
67738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            native_handle_t *handle = native_handle_clone(cHandle);
678878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            if (handle) {
679878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                std::shared_ptr<C2LinearAllocation> alloc;
680878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                std::shared_ptr<C2PooledBlockPoolData> poolData =
681878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                        std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
682878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                c2_status_t err = mAllocator->priorLinearAllocation(handle, &alloc);
683878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                if (err == C2_OK && poolData && alloc) {
684878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    *block = _C2BlockFactory::CreateLinearBlock(alloc, poolData, 0, capacity);
685878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    if (*block) {
686878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                        return C2_OK;
687878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    }
6884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
6894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
6904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_NO_MEMORY;
6914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (status == ResultStatus::NO_MEMORY) {
6934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_NO_MEMORY;
6944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
6954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_CORRUPTED;
6964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6984a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    c2_status_t fetchGraphicBlock(
6994a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            uint32_t width, uint32_t height, uint32_t format,
7004a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            C2MemoryUsage usage,
7014a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            std::shared_ptr<C2GraphicBlock> *block) {
7024a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        block->reset();
7034a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        if (mInit != C2_OK) {
7044a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            return mInit;
7054a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        }
7064a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        std::vector<uint8_t> params;
7074a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        mAllocator->getGraphicParams(width, height, format, usage, &params);
7084a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        std::shared_ptr<BufferPoolData> bufferPoolData;
7094a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        native_handle_t *cHandle = nullptr;
7104a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        ResultStatus status = mBufferPoolManager->allocate(
7114a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                mConnectionId, params, &cHandle, &bufferPoolData);
7124a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        if (status == ResultStatus::OK) {
7134a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            native_handle_t *handle = native_handle_clone(cHandle);
7144a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            if (handle) {
7154a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                std::shared_ptr<C2GraphicAllocation> alloc;
7164a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                std::shared_ptr<C2PooledBlockPoolData> poolData =
7174a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
7184a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                c2_status_t err = mAllocator->priorGraphicAllocation(
7194a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        handle, &alloc);
7204a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                if (err == C2_OK && poolData && alloc) {
7214a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    *block = _C2BlockFactory::CreateGraphicBlock(
7224a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                            alloc, poolData, C2Rect(width, height));
7234a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    if (*block) {
7244a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                        return C2_OK;
7254a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                    }
7264a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa                }
7274a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            }
7284a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            return C2_NO_MEMORY;
7294a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        }
7304a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        if (status == ResultStatus::NO_MEMORY) {
7314a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa            return C2_NO_MEMORY;
7324a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        }
7334a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        return C2_CORRUPTED;
7344a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    }
7354a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa
736878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    ConnectionId getConnectionId() {
73738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        return mInit != C2_OK ? INVALID_CONNECTIONID : mConnectionId;
738878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
739878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
7404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
7414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t mInit;
7424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const android::sp<ClientManager> mBufferPoolManager;
7434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ConnectionId mConnectionId; // locally
7444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::shared_ptr<_C2BufferPoolAllocator> mAllocator;
7454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
7464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PooledBlockPool::C2PooledBlockPool(
7484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId)
7494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mAllocator(allocator), mLocalId(localId), mImpl(new Impl(allocator)) {}
7504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2PooledBlockPool::~C2PooledBlockPool() {
7524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2PooledBlockPool::fetchLinearBlock(
7554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t capacity,
7564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2MemoryUsage usage,
7574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
7584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mImpl) {
7594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mImpl->fetchLinearBlock(capacity, usage, block);
7604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
7614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_CORRUPTED;
7624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
7634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7644a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasac2_status_t C2PooledBlockPool::fetchGraphicBlock(
7654a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        uint32_t width,
7664a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        uint32_t height,
7674a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        uint32_t format,
7684a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        C2MemoryUsage usage,
7694a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        std::shared_ptr<C2GraphicBlock> *block) {
7704a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    if (mImpl) {
7714a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa        return mImpl->fetchGraphicBlock(width, height, format, usage, block);
7724a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    }
7734a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa    return C2_CORRUPTED;
7744a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa}
7754a3e4577f5c1c9bd9f52f23f42fbc92a1c869b79Pawin Vongmasa
776878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leeint64_t C2PooledBlockPool::getConnectionId() {
777878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    if (mImpl) {
778878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        return mImpl->getConnectionId();
779878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
780878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return 0;
781878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee}
782878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
7834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* ========================================== 2D BLOCK ========================================= */
7844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
7854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
7864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Implementation that is shared between all 2D blocks and views.
7874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
7884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * For blocks' Impl's crop is always the allotted crop, even if it is a sub block.
7894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
7904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * For views' Impl's crop is the mapped portion - which for now is always the
7914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * allotted crop.
7924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
7934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2_HIDE _C2Block2DImpl : public _C2PlanarSectionAspect {
7944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
7954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
7964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Impl's crop is always the or part of the allotted crop of the allocation.
7974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
7984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2Block2DImpl(const std::shared_ptr<C2GraphicAllocation> &alloc,
7994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
8004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const C2Rect &allottedCrop = C2Rect(~0u, ~0u))
8014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2PlanarSectionAspect(alloc.get(), allottedCrop),
8024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mAllocation(alloc),
8034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mPoolData(poolData) { }
8044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
805d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar    virtual ~_C2Block2DImpl() = default;
806d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar
8072cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa    /** returns pool data  */
8082cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasa    std::shared_ptr<_C2BlockPoolData> poolData() const {
8094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mPoolData;
8104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /** returns native handle */
8134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const C2Handle *handle() const {
8144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation ? mAllocation->handle() : nullptr;
8154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /** returns the allocator's ID */
8184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2Allocator::id_t getAllocatorId() const {
8194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
8204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
8214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2GraphicAllocation> getAllocation() const {
8244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAllocation;
8254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
8264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
8284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2GraphicAllocation> mAllocation;
8294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2BlockPoolData> mPoolData;
8304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
8314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2_HIDE _C2MappingBlock2DImpl
8334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : public _C2Block2DImpl, public std::enable_shared_from_this<_C2MappingBlock2DImpl> {
8344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
8354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2Block2DImpl::_C2Block2DImpl;
8364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
837d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar    virtual ~_C2MappingBlock2DImpl() override = default;
838d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar
8394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
8404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * This class contains the mapped data pointer, and the potential error.
8414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
8424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct Mapped {
8434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
8444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        friend class _C2MappingBlock2DImpl;
8454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        Mapped(const std::shared_ptr<_C2Block2DImpl> &impl, bool writable, C2Fence *fence __unused)
8474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mImpl(impl), mWritable(writable) {
8484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            memset(mData, 0, sizeof(mData));
8494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const C2Rect crop = mImpl->crop();
8504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // gralloc requires mapping the whole region of interest as we cannot
8514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // map multiple regions
8524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mError = mImpl->getAllocation()->map(
8534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    crop,
8544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    { C2MemoryUsage::CPU_READ, writable ? C2MemoryUsage::CPU_WRITE : 0 },
8554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    nullptr,
8564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    &mLayout,
8574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mData);
8584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mError != C2_OK) {
8594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                memset(&mLayout, 0, sizeof(mLayout));
8604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                memset(mData, 0, sizeof(mData));
8614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                memset(mOffsetData, 0, sizeof(mData));
8624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            } else {
8634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // TODO: validate plane layout and
8644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // adjust data pointers to the crop region's top left corner.
8654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // fail if it is not on a subsampling boundary
8664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                for (size_t planeIx = 0; planeIx < mLayout.numPlanes; ++planeIx) {
8674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    const uint32_t colSampling = mLayout.planes[planeIx].colSampling;
8684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    const uint32_t rowSampling = mLayout.planes[planeIx].rowSampling;
8694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (crop.left % colSampling || crop.right() % colSampling
8704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            || crop.top % rowSampling || crop.bottom() % rowSampling) {
8714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        // cannot calculate data pointer
8724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        mImpl->getAllocation()->unmap(mData, crop, nullptr);
8734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        memset(&mLayout, 0, sizeof(mLayout));
8744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        memset(mData, 0, sizeof(mData));
8754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        memset(mOffsetData, 0, sizeof(mData));
8764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        mError = C2_BAD_VALUE;
8774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        return;
8784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
8794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mOffsetData[planeIx] =
8804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        mData[planeIx] + (ssize_t)crop.left * mLayout.planes[planeIx].colInc
8814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                                + (ssize_t)crop.top * mLayout.planes[planeIx].rowInc;
8824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
8834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
8844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        explicit Mapped(c2_status_t error)
8874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mImpl(nullptr), mWritable(false), mError(error) {
8884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // CHECK(error != C2_OK);
8894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            memset(&mLayout, 0, sizeof(mLayout));
8904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            memset(mData, 0, sizeof(mData));
8914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            memset(mOffsetData, 0, sizeof(mData));
8924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
8934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
8944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    public:
8954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ~Mapped() {
8964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (mData[0] != nullptr) {
8974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mImpl->getAllocation()->unmap(mData, mImpl->crop(), nullptr);
8984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
8994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
9004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /** returns mapping status */
9024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t error() const { return mError; }
9034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /** returns data pointer */
9054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint8_t *const *data() const { return mOffsetData; }
9064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /** returns the plane layout */
9084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlanarLayout layout() const { return mLayout; }
9094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        /** returns whether the mapping is writable */
9114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        bool writable() const { return mWritable; }
9124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    private:
9144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<_C2Block2DImpl> mImpl;
9154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        bool mWritable;
9164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        c2_status_t mError;
9174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint8_t *mData[C2PlanarLayout::MAX_NUM_PLANES];
9184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint8_t *mOffsetData[C2PlanarLayout::MAX_NUM_PLANES];
9194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2PlanarLayout mLayout;
9204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    };
9214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    /**
9234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * Maps the allotted region.
9244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     *
9254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * If already mapped and it is currently in use, returns the existing mapping.
9264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     * If fence is provided, an acquire fence is stored there.
9274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim     */
9284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<Mapped> map(bool writable, C2Fence *fence) {
9294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::lock_guard<std::mutex> lock(mMappedLock);
9304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<Mapped> existing = mMapped.lock();
9314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (!existing) {
9324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            existing = std::shared_ptr<Mapped>(new Mapped(shared_from_this(), writable, fence));
9334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mMapped = existing;
9344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
9354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // if we mapped the region read-only, we cannot remap it read-write
9364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (writable && !existing->writable()) {
9374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                existing = std::shared_ptr<Mapped>(new Mapped(C2_CANNOT_DO));
9384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
9394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (fence != nullptr) {
9404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                *fence = C2Fence();
9414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
9424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
9434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return existing;
9444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
9454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
9474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::weak_ptr<Mapped> mMapped;
9484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::mutex mMappedLock;
9494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
9504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2_HIDE _C2MappedBlock2DImpl : public _C2Block2DImpl {
9524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
9534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    _C2MappedBlock2DImpl(const _C2Block2DImpl &impl,
9544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                         std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping)
9554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : _C2Block2DImpl(impl), mMapping(mapping) {
9564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
9574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
958d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar    virtual ~_C2MappedBlock2DImpl() override = default;
959d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar
9604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping() const { return mMapping; }
9614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
9634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mMapping;
9644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
9654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
9674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Block implementation.
9684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
9694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2Block2D::Impl : public _C2MappingBlock2DImpl {
970d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnarpublic:
9714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2MappingBlock2DImpl::_C2MappingBlock2DImpl;
972d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar    virtual ~Impl() override = default;
9734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
9744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst C2Handle *C2Block2D::handle() const {
9764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->handle();
9774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Allocator::id_t C2Block2D::getAllocatorId() const {
9804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->getAllocatorId();
9814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Block2D::C2Block2D(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
9844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // always clamp subsection to parent (impl) crop for safety
9854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2PlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
9864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
9874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
9884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
9894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Graphic view implementation.
9904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim *
9914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * range of Impl is the mapped range of the underlying allocation. range of View is the current
9924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * crop.
9934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
9944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2GraphicView::Impl : public _C2MappedBlock2DImpl {
995d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnarpublic:
9964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    using _C2MappedBlock2DImpl::_C2MappedBlock2DImpl;
997d13c51caeec5e2104e33a4dca34eeb8ad2f3d804Lajos Molnar    virtual ~Impl() override = default;
9984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
9994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2GraphicView::C2GraphicView(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
10014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : _C2EditablePlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
10024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst uint8_t *const *C2GraphicView::data() const {
10054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->mapping()->data();
10064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimuint8_t *const *C2GraphicView::data() {
10094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->mapping()->data();
10104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst C2PlanarLayout C2GraphicView::layout() const {
10134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->mapping()->layout();
10144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst C2GraphicView C2GraphicView::subView(const C2Rect &rect) const {
10174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
10184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2GraphicView C2GraphicView::subView(const C2Rect &rect) {
10214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
10224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2GraphicView::error() const {
10254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->mapping()->error();
10264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
10294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Const graphic block implementation.
10304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
10314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstGraphicBlock::C2ConstGraphicBlock(
10324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section, C2Fence fence)
10334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : C2Block2D(impl, section), mFence(fence) { }
10344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Acquirable<const C2GraphicView> C2ConstGraphicBlock::map() const {
10364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2Fence fence;
10374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
10384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mImpl->map(false /* writable */, &fence);
10394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
10404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
10414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return AcquirableConstGraphicViewBuddy(
10424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
10434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstGraphicBlock C2ConstGraphicBlock::subBlock(const C2Rect &rect) const {
10464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2ConstGraphicBlock(mImpl, C2PlanarSection(*mImpl, crop().intersect(rect)), mFence);
10474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
10504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Graphic block implementation.
10514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
10524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2GraphicBlock::C2GraphicBlock(
10534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
10544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : C2Block2D(impl, section) { }
10554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Acquirable<C2GraphicView> C2GraphicBlock::map() {
10574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2Fence fence;
10584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
10594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mImpl->map(true /* writable */, &fence);
10604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
10614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
10624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return AcquirableGraphicViewBuddy(
10634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
10644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2ConstGraphicBlock C2GraphicBlock::share(const C2Rect &crop, C2Fence fence) {
10674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ConstGraphicBlockBuddy(mImpl, C2PlanarSection(*mImpl, crop), fence);
10684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/**
10714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Basic block pool implementations.
10724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim */
10734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2BasicGraphicBlockPool::C2BasicGraphicBlockPool(
10744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2Allocator> &allocator)
10754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim  : mAllocator(allocator) {}
10764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2BasicGraphicBlockPool::fetchGraphicBlock(
10784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t width,
10794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t height,
10804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        uint32_t format,
10814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        C2MemoryUsage usage,
10824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
10834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    block->reset();
10844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2GraphicAllocation> alloc;
10864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t err = mAllocator->newGraphicAllocation(width, height, format, usage, &alloc);
10874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (err != C2_OK) {
10884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return err;
10894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
10904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    *block = _C2BlockFactory::CreateGraphicBlock(alloc);
10924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return C2_OK;
10944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
10954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
10964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
10974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<C2GraphicAllocation> &alloc,
10984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::shared_ptr<_C2BlockPoolData> &data, const C2Rect &allottedCrop) {
10994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Block2D::Impl> impl =
11004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::make_shared<C2Block2D::Impl>(alloc, data, allottedCrop);
11014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::shared_ptr<C2GraphicBlock>(new C2GraphicBlock(impl, *impl));
11024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
11034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11042cc26aada0fc1c80eb2564eb19f1b085380d07b9Pawin Vongmasastd::shared_ptr<_C2BlockPoolData> _C2BlockFactory::GetGraphicBlockPoolData(
1105878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const C2Block2D &block) {
1106878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    if (block.mImpl) {
1107878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        return block.mImpl->poolData();
1108878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
1109878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return nullptr;
1110878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee}
1111878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
1112878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Leestd::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
111338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        const C2Handle *cHandle,
1114878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        const std::shared_ptr<BufferPoolData> &data) {
1115878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    // TODO: get proper allocator? and mutex?
1116878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    static std::unique_ptr<C2AllocatorGralloc> sAllocator = std::make_unique<C2AllocatorGralloc>(0);
1117878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
1118878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    std::shared_ptr<C2GraphicAllocation> alloc;
111938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    if (C2AllocatorGralloc::isValid(cHandle)) {
112038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t *handle = native_handle_clone(cHandle);
1121878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        if (handle) {
1122878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            c2_status_t err = sAllocator->priorGraphicAllocation(handle, &alloc);
1123878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            const std::shared_ptr<C2PooledBlockPoolData> poolData =
1124878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                    std::make_shared<C2PooledBlockPoolData>(data);
1125878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            if (err == C2_OK && poolData) {
1126878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                // TODO: config setup?
1127878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                std::shared_ptr<C2GraphicBlock> block =
1128878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                        _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
1129878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee                return block;
1130878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            }
1131878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee        }
1132878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    }
1133878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    return nullptr;
1134878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee};
1135878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
1136878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee
11374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/* ========================================== BUFFER ========================================= */
11384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2BufferData::Impl {
11404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
11414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    explicit Impl(const std::vector<C2ConstLinearBlock> &blocks)
11424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mType(blocks.size() == 1 ? LINEAR : LINEAR_CHUNKS),
11434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mLinearBlocks(blocks) {
11444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
11454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    explicit Impl(const std::vector<C2ConstGraphicBlock> &blocks)
11474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mType(blocks.size() == 1 ? GRAPHIC : GRAPHIC_CHUNKS),
11484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          mGraphicBlocks(blocks) {
11494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
11504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1151c406604d66cd8aa7ead7fdb7647d90ccae0a1a29Lajos Molnar    type_t type() const { return mType; }
11524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::vector<C2ConstLinearBlock> &linearBlocks() const { return mLinearBlocks; }
11534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::vector<C2ConstGraphicBlock> &graphicBlocks() const { return mGraphicBlocks; }
11544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
1156c406604d66cd8aa7ead7fdb7647d90ccae0a1a29Lajos Molnar    type_t mType;
11574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2ConstLinearBlock> mLinearBlocks;
11584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<C2ConstGraphicBlock> mGraphicBlocks;
11594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
11604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2BufferData::C2BufferData(const std::vector<C2ConstLinearBlock> &blocks) : mImpl(new Impl(blocks)) {}
11624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2BufferData::C2BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : mImpl(new Impl(blocks)) {}
11634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1164c406604d66cd8aa7ead7fdb7647d90ccae0a1a29Lajos MolnarC2BufferData::type_t C2BufferData::type() const { return mImpl->type(); }
11654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst std::vector<C2ConstLinearBlock> C2BufferData::linearBlocks() const {
11674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->linearBlocks();
11684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
11694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst std::vector<C2ConstGraphicBlock> C2BufferData::graphicBlocks() const {
11714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->graphicBlocks();
11724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
11734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass C2Buffer::Impl {
11754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
11764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Impl(C2Buffer *thiz, const std::vector<C2ConstLinearBlock> &blocks)
11774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mThis(thiz), mData(blocks) {}
11784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    Impl(C2Buffer *thiz, const std::vector<C2ConstGraphicBlock> &blocks)
11794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : mThis(thiz), mData(blocks) {}
11804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ~Impl() {
11824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        for (const auto &pair : mNotify) {
11834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            pair.first(mThis, pair.second);
11844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
11854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
11864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const C2BufferData &data() const { return mData; }
11884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
11894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
11904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto it = std::find_if(
11914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mNotify.begin(), mNotify.end(),
11924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [onDestroyNotify, arg] (const auto &pair) {
11934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    return pair.first == onDestroyNotify && pair.second == arg;
11944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                });
11954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (it != mNotify.end()) {
11964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_DUPLICATE;
11974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
11984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mNotify.emplace_back(onDestroyNotify, arg);
11994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_OK;
12004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
12034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto it = std::find_if(
12044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mNotify.begin(), mNotify.end(),
12054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [onDestroyNotify, arg] (const auto &pair) {
12064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    return pair.first == onDestroyNotify && pair.second == arg;
12074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                });
12084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (it == mNotify.end()) {
12094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return C2_NOT_FOUND;
12104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
12114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mNotify.erase(it);
12124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_OK;
12134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::vector<std::shared_ptr<const C2Info>> info() const {
12164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::vector<std::shared_ptr<const C2Info>> result(mInfos.size());
12174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::transform(
12184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mInfos.begin(), mInfos.end(), result.begin(),
12194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                [] (const auto &elem) { return elem.second; });
12204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return result;
12214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    c2_status_t setInfo(const std::shared_ptr<C2Info> &info) {
12244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // To "update" you need to erase the existing one if any, and then insert.
1225dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        (void) mInfos.erase(info->coreIndex());
1226dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        (void) mInfos.insert({ info->coreIndex(), info });
12274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return C2_OK;
12284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool hasInfo(C2Param::Type index) const {
1231dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        return mInfos.count(index.coreIndex()) > 0;
1232dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar    }
1233dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar
1234dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar    std::shared_ptr<const C2Info> getInfo(C2Param::Type index) const {
1235dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        auto it = mInfos.find(index.coreIndex());
1236dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        if (it == mInfos.end()) {
1237dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar            return nullptr;
1238dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        }
1239dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        return std::const_pointer_cast<const C2Info>(it->second);
12404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::shared_ptr<C2Info> removeInfo(C2Param::Type index) {
1243dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar        auto it = mInfos.find(index.coreIndex());
12444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (it == mInfos.end()) {
12454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return nullptr;
12464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
12474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::shared_ptr<C2Info> ret = it->second;
12484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        (void) mInfos.erase(it);
12494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ret;
12504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
12514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
12534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    C2Buffer * const mThis;
12544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    BufferDataBuddy mData;
1255dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar    std::map<C2Param::CoreIndex, std::shared_ptr<C2Info>> mInfos;
12564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::list<std::pair<OnDestroyNotify, void *>> mNotify;
12574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
12584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Buffer::C2Buffer(const std::vector<C2ConstLinearBlock> &blocks)
12604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : mImpl(new Impl(this, blocks)) {}
12614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimC2Buffer::C2Buffer(const std::vector<C2ConstGraphicBlock> &blocks)
12634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    : mImpl(new Impl(this, blocks)) {}
12644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst C2BufferData C2Buffer::data() const { return mImpl->data(); }
12664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2Buffer::registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
12684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->registerOnDestroyNotify(onDestroyNotify, arg);
12694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2Buffer::unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
12724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->unregisterOnDestroyNotify(onDestroyNotify, arg);
12734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimconst std::vector<std::shared_ptr<const C2Info>> C2Buffer::info() const {
12764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->info();
12774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimc2_status_t C2Buffer::setInfo(const std::shared_ptr<C2Info> &info) {
12804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->setInfo(info);
12814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool C2Buffer::hasInfo(C2Param::Type index) const {
12844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->hasInfo(index);
12854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1287dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnarstd::shared_ptr<const C2Info> C2Buffer::getInfo(C2Param::Type index) const {
1288dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar    return mImpl->getInfo(index);
1289dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar}
1290dec0d49536acd2fb3df7380f989d1b63104eae14Lajos Molnar
12914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Info> C2Buffer::removeInfo(C2Param::Type index) {
12924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl->removeInfo(index);
12934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
12954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// static
12964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> C2Buffer::CreateLinearBuffer(const C2ConstLinearBlock &block) {
12974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
12984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
12994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
13004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// static
13014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstd::shared_ptr<C2Buffer> C2Buffer::CreateGraphicBuffer(const C2ConstGraphicBlock &block) {
13024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
13034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
13044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1305