14344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim/*
24344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim * Copyright (C) 2018 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
176c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee#define LOG_TAG "BufferPoolClient"
184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim//#define LOG_NDEBUG 0
194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <thread>
214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include <utils/Log.h>
224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include "BufferPoolClient.h"
234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim#include "Connection.h"
244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace android {
264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace hardware {
274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace media {
284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace bufferpool {
294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace V1_0 {
304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimnamespace implementation {
314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
32da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Leestatic constexpr int64_t kReceiveTimeoutUs = 1000000; // 100ms
334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstatic constexpr int kPostMaxRetry = 3;
34da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Leestatic constexpr int kCacheTtlUs = 1000000; // TODO: tune
354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimclass BufferPoolClient::Impl
374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        : public std::enable_shared_from_this<BufferPoolClient::Impl> {
384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    explicit Impl(const sp<Accessor> &accessor);
404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    explicit Impl(const sp<IAccessor> &accessor);
424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool isValid() {
444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mValid;
454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4771252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee    bool isLocal() {
4871252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee        return mValid && mLocal;
4971252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee    }
5071252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee
514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ConnectionId getConnectionId() {
524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mConnectionId;
534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<IAccessor> &getAccessor() {
564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mAccessor;
574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
59da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    bool isActive(int64_t *lastTransactionUs, bool clearCache);
60da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus allocate(const std::vector<uint8_t> &params,
6238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                          native_handle_t **handle,
6338a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                          std::shared_ptr<BufferPoolData> *buffer);
644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus receive(
664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            TransactionId transactionId, BufferId bufferId,
6738a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            int64_t timestampUs,
6838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void postBufferRelease(BufferId bufferId);
714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool postSend(
734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            BufferId bufferId, ConnectionId receiver,
744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            TransactionId *transactionId, int64_t *timestampUs);
754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool postReceive(
784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            BufferId bufferId, TransactionId transactionId,
794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            int64_t timestampUs);
804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool postReceiveResult(
824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            BufferId bufferId, TransactionId transactionId, bool result);
834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool syncReleased();
854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
86da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    void evictCaches(bool clearCache = false);
87da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus allocateBufferHandle(
894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            const std::vector<uint8_t>& params, BufferId *bufferId,
904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            native_handle_t **handle);
914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus fetchBufferHandle(
934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            TransactionId transactionId, BufferId bufferId,
944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            native_handle_t **handle);
954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct BlockPoolDataDtor;
984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct ClientBuffer;
994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool mLocal;
1014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool mValid;
1024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<IAccessor> mAccessor;
1034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<Connection> mLocalConnection;
1044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<IConnection> mRemoteConnection;
1054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    uint32_t mSeqId;
1064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ConnectionId mConnectionId;
107da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    int64_t mLastEvictCacheUs;
1084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // CachedBuffers
110bc01c75a0c508c5cd6de9e2eeb478cd74256a8a5Sungtak Lee    struct BufferCache {
1114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mLock;
112bc01c75a0c508c5cd6de9e2eeb478cd74256a8a5Sungtak Lee        bool mCreating;
1134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::condition_variable mCreateCv;
1144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
115da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        int mActive;
116da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        int64_t mLastChangeUs;
117da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
118da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        BufferCache() : mCreating(false), mActive(0), mLastChangeUs(getTimestampNow()) {}
119da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
120da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        void incActive_l() {
121da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            ++mActive;
122da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            mLastChangeUs = getTimestampNow();
123da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        }
124da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
125da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        void decActive_l() {
126da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            --mActive;
127da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            mLastChangeUs = getTimestampNow();
128da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        }
1294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } mCache;
1304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // FMQ - release notifier
1324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    struct {
1334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::mutex mLock;
1344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        // TODO: use only one list?(using one list may dealy sending messages?)
1354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::list<BufferId> mReleasingIds;
1364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::list<BufferId> mReleasedIds;
1374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_ptr<BufferStatusChannel> mStatusChannel;
1384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } mReleasing;
1394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct BufferPoolClient::Impl::BlockPoolDataDtor {
1424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
1434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            : mImpl(impl) {}
1444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1456c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee    void operator()(BufferPoolData *buffer) {
1464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        BufferId id = buffer->mId;
1474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        delete buffer;
1484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto impl = mImpl.lock();
1504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (impl && impl->isValid()) {
1514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            impl->postBufferRelease(id);
1524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const std::weak_ptr<BufferPoolClient::Impl> mImpl;
1554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
1564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimstruct BufferPoolClient::Impl::ClientBuffer {
1584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimprivate:
1594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool mInvalidated; // TODO: implement
1604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    int64_t mExpireUs;
1614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool mHasCache;
162878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    ConnectionId mConnectionId;
1634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    BufferId mId;
1644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    native_handle_t *mHandle;
1656c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee    std::weak_ptr<BufferPoolData> mCache;
1664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    void updateExpire() {
1684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mExpireUs = getTimestampNow() + kCacheTtlUs;
1694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimpublic:
172878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee    ClientBuffer(
173546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee            ConnectionId connectionId, BufferId id, native_handle_t *handle)
174878e45a7f16a9a68b322f7bdb369bf653a0f66cbSungtak Lee            : mInvalidated(false), mHasCache(false),
175546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee              mConnectionId(connectionId), mId(id), mHandle(handle) {
1764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        (void)mInvalidated;
1774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mExpireUs = getTimestampNow() + kCacheTtlUs;
1784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ~ClientBuffer() {
1814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mHandle) {
1824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            native_handle_close(mHandle);
1834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            native_handle_delete(mHandle);
1844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
1854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool expire() const {
1884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        int64_t now = getTimestampNow();
1894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return now >= mExpireUs;
1904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
1924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool hasCache() const {
1934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mHasCache;
1944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
1954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
19638a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee    std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
1974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mHasCache) {
1986c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee            std::shared_ptr<BufferPoolData> cache = mCache.lock();
1994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (cache) {
20038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                *pHandle = mHandle;
2014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
2024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return cache;
2034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return nullptr;
2054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2076c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee    std::shared_ptr<BufferPoolData> createCache(
20838a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            const std::shared_ptr<BufferPoolClient::Impl> &impl,
20938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            native_handle_t **pHandle) {
2104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (!mHasCache) {
2114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // Allocates a raw ptr in order to avoid sending #postBufferRelease
2124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // from deleter, in case of native_handle_clone failure.
213546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee            BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
21438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee            if (ptr) {
215546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee                std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
2164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (cache) {
2174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mCache = cache;
2184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mHasCache = true;
21938a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                    *pHandle = mHandle;
2204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    return cache;
2214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
2224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
2234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (ptr) {
2244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                delete ptr;
2254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
2264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return nullptr;
2284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool onCacheRelease() {
2314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (mHasCache) {
2324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            // TODO: verify mCache is not valid;
233da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            updateExpire();
2344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mHasCache = false;
2354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return true;
2364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
2374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return false;
2384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim};
2404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimBufferPoolClient::Impl::Impl(const sp<Accessor> &accessor)
2420b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
243da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee      mLastEvictCacheUs(getTimestampNow()) {
2444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    const QueueDescriptor *fmqDesc;
2454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus status = accessor->connect(
24671252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee            &mLocalConnection, &mConnectionId, &fmqDesc, true);
2474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (status == ResultStatus::OK) {
2484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mReleasing.mStatusChannel =
2494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                std::make_unique<BufferStatusChannel>(*fmqDesc);
2504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mValid = mReleasing.mStatusChannel &&
2514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mReleasing.mStatusChannel->isValid();
2524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
2534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
2554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimBufferPoolClient::Impl::Impl(const sp<IAccessor> &accessor)
2560b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
257da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee      mLastEvictCacheUs(getTimestampNow()) {
2580b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    bool valid = false;
2594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<IConnection>& outConnection = mRemoteConnection;
2604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ConnectionId& id = mConnectionId;
2614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::unique_ptr<BufferStatusChannel>& outChannel =
2624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mReleasing.mStatusChannel;
2630b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    Return<void> transResult = accessor->connect(
2644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            [&valid, &outConnection, &id, &outChannel]
2654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (ResultStatus status, sp<IConnection> connection,
2664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim             ConnectionId connectionId, const QueueDescriptor& desc) {
2674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (status == ResultStatus::OK) {
2684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    outConnection = connection;
2694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    id = connectionId;
2704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    outChannel = std::make_unique<BufferStatusChannel>(desc);
2714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (outChannel && outChannel->isValid()) {
2724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        valid = true;
2734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
2744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
2754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            });
2760b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    mValid = transResult.isOk() && valid;
2774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
2784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
279da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Leebool BufferPoolClient::Impl::isActive(int64_t *lastTransactionUs, bool clearCache) {
280da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    {
281da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        std::lock_guard<std::mutex> lock(mCache.mLock);
282da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        syncReleased();
283da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        evictCaches(clearCache);
284da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        *lastTransactionUs = mCache.mLastChangeUs;
285da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    }
286da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    if (mValid && mLocal && mLocalConnection) {
287da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        mLocalConnection->cleanUp(clearCache);
288da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        return true;
289da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    }
290da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    return mCache.mActive > 0;
291da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee}
292da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
2934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::Impl::allocate(
2944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t> &params,
29538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t **pHandle,
2966c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee        std::shared_ptr<BufferPoolData> *buffer) {
2974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mLocal || !mLocalConnection || !mValid) {
2984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ResultStatus::CRITICAL_ERROR;
2994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    BufferId bufferId;
3014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    native_handle_t *handle = NULL;
3024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    buffer->reset();
3034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus status = allocateBufferHandle(params, &bufferId, &handle);
3044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (status == ResultStatus::OK) {
3054344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (handle) {
3064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::unique_lock<std::mutex> lock(mCache.mLock);
3074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            syncReleased();
308da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            evictCaches();
3094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            auto cacheIt = mCache.mBuffers.find(bufferId);
3104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (cacheIt != mCache.mBuffers.end()) {
3114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // TODO: verify it is recycled. (not having active ref)
3124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mCache.mBuffers.erase(cacheIt);
3134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            auto clientBuffer = std::make_unique<ClientBuffer>(
315546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee                    mConnectionId, bufferId, handle);
3164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (clientBuffer) {
3174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                auto result = mCache.mBuffers.insert(std::make_pair(
3184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        bufferId, std::move(clientBuffer)));
3194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (result.second) {
3204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    *buffer = result.first->second->createCache(
32138a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                            shared_from_this(), pHandle);
322da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                    if (*buffer) {
323da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                        mCache.incActive_l();
324da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                    }
3254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
3264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (!*buffer) {
3296c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee            ALOGV("client cache creation failure %d: %lld",
3306c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                  handle != NULL, (long long)mConnectionId);
3314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            status = ResultStatus::NO_MEMORY;
3324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            postBufferRelease(bufferId);
3334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
3344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return status;
3364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
3374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
3384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::Impl::receive(
3394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
34038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t **pHandle,
3416c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee        std::shared_ptr<BufferPoolData> *buffer) {
3424344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!mValid) {
3434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ResultStatus::CRITICAL_ERROR;
3444344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (timestampUs != 0) {
3464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        timestampUs += kReceiveTimeoutUs;
3474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (!postReceive(bufferId, transactionId, timestampUs)) {
3494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ResultStatus::CRITICAL_ERROR;
3504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
3514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus status = ResultStatus::CRITICAL_ERROR;
3524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    buffer->reset();
3534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    while(1) {
3544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_lock<std::mutex> lock(mCache.mLock);
3554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        syncReleased();
356da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        evictCaches();
3574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        auto cacheIt = mCache.mBuffers.find(bufferId);
3584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (cacheIt != mCache.mBuffers.end()) {
3594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (cacheIt->second->hasCache()) {
36038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                *buffer = cacheIt->second->fetchCache(pHandle);
3614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (!*buffer) {
3624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    // check transfer time_out
3634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    lock.unlock();
3644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    std::this_thread::yield();
3654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    continue;
3664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
3676c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                ALOGV("client receive from reference %lld", (long long)mConnectionId);
3684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                break;
3694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            } else {
37038a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
371da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                if (*buffer) {
372da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                    mCache.incActive_l();
373da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                }
3746c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                ALOGV("client receive from cache %lld", (long long)mConnectionId);
3754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                break;
3764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
3774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
378bc01c75a0c508c5cd6de9e2eeb478cd74256a8a5Sungtak Lee            if (!mCache.mCreating) {
379bc01c75a0c508c5cd6de9e2eeb478cd74256a8a5Sungtak Lee                mCache.mCreating = true;
3804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                lock.unlock();
3814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                native_handle_t* handle = NULL;
3824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                status = fetchBufferHandle(transactionId, bufferId, &handle);
3834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                lock.lock();
3844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (status == ResultStatus::OK) {
3854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (handle) {
3864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        auto clientBuffer = std::make_unique<ClientBuffer>(
387546fd714e7c4e53e6c05a9e5fb5c04c3c7ad381eSungtak Lee                                mConnectionId, bufferId, handle);
3884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        if (clientBuffer) {
3894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            auto result = mCache.mBuffers.insert(
3904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                                    std::make_pair(bufferId, std::move(
3914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                                            clientBuffer)));
3924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            if (result.second) {
3934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                                *buffer = result.first->second->createCache(
39438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee                                        shared_from_this(), pHandle);
395da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                                if (*buffer) {
396da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                                    mCache.incActive_l();
397da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                                }
3984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            }
3994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        }
4004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
4014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    if (!*buffer) {
4024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                        status = ResultStatus::NO_MEMORY;
4034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    }
4044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
405bc01c75a0c508c5cd6de9e2eeb478cd74256a8a5Sungtak Lee                mCache.mCreating = false;
4064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                lock.unlock();
4074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mCache.mCreateCv.notify_all();
4084344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                break;
4094344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4104344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mCache.mCreateCv.wait(lock);
4114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4124344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4134344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    bool posted = postReceiveResult(bufferId, transactionId,
4144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                                      *buffer ? true : false);
4156c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee    ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
4164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim          *buffer ? "ok" : "fail", posted);
4177da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    if (mValid && mLocal && mLocalConnection) {
4187da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        mLocalConnection->cleanUp(false);
4197da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    }
4204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (*buffer) {
4214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (!posted) {
4224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            buffer->reset();
4234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return ResultStatus::CRITICAL_ERROR;
4244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ResultStatus::OK;
4264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return status;
4284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimvoid BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
4324344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mReleasing.mLock);
4334344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mReleasing.mReleasingIds.push_back(bufferId);
4344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mReleasing.mStatusChannel->postBufferRelease(
4354344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
4364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// TODO: revise ad-hoc posting data structure
4394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool BufferPoolClient::Impl::postSend(
4404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        BufferId bufferId, ConnectionId receiver,
4414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TransactionId *transactionId, int64_t *timestampUs) {
4427da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    bool ret = false;
4437da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    {
4447da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        std::lock_guard<std::mutex> lock(mReleasing.mLock);
4457da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        *timestampUs = getTimestampNow();
4467da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        *transactionId = (mConnectionId << 32) | mSeqId++;
4477da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        // TODO: retry, add timeout, target?
4487da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        ret =  mReleasing.mStatusChannel->postBufferStatusMessage(
4497da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee                *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
4507da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee                receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
4517da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    }
4527da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    if (mValid && mLocal && mLocalConnection) {
4537da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee        mLocalConnection->cleanUp(false);
4547da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    }
4557da42e0823f20c3cc93bcd998bfb39f41b3f44f9Sungtak Lee    return ret;
4564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool BufferPoolClient::Impl::postReceive(
4594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        BufferId bufferId, TransactionId transactionId, int64_t timestampUs) {
4604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    for (int i = 0; i < kPostMaxRetry; ++i) {
4614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        std::unique_lock<std::mutex> lock(mReleasing.mLock);
4624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        int64_t now = getTimestampNow();
4634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (timestampUs == 0 || now < timestampUs) {
4644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
4654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    transactionId, bufferId, BufferStatus::TRANSFER_FROM,
4664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mConnectionId, -1, mReleasing.mReleasingIds,
4674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mReleasing.mReleasedIds);
4684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (result) {
4694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                return true;
4704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
4714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            lock.unlock();
4724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            std::this_thread::yield();
4734344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        } else {
4744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mReleasing.mStatusChannel->postBufferStatusMessage(
4754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
4764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mConnectionId, -1, mReleasing.mReleasingIds,
4774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    mReleasing.mReleasedIds);
4784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            return false;
4794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
4804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
4814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return false;
4824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4834344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool BufferPoolClient::Impl::postReceiveResult(
4854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        BufferId bufferId, TransactionId transactionId, bool result) {
4864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mReleasing.mLock);
4874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: retry, add timeout
4884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mReleasing.mStatusChannel->postBufferStatusMessage(
4894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            transactionId, bufferId,
4904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
4914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mConnectionId, -1, mReleasing.mReleasingIds,
4924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            mReleasing.mReleasedIds);
4934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
4944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
4954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim// should have mCache.mLock
4964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool BufferPoolClient::Impl::syncReleased() {
4974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    std::lock_guard<std::mutex> lock(mReleasing.mLock);
4984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mReleasing.mReleasingIds.size() > 0) {
4994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mReleasing.mStatusChannel->postBufferRelease(
5004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mConnectionId, mReleasing.mReleasingIds,
5014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                mReleasing.mReleasedIds);
5024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5034344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mReleasing.mReleasedIds.size() > 0) {
5044344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        for (BufferId& id: mReleasing.mReleasedIds) {
5056c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee            ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
5064344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            auto found = mCache.mBuffers.find(id);
5074344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            if (found != mCache.mBuffers.end()) {
508da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                if (found->second->onCacheRelease()) {
509da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                    mCache.decActive_l();
510da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                } else {
5114344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    // should not happen!
5126c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                    ALOGW("client %lld cache release status inconsitent!",
5136c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                          (long long)mConnectionId);
5144344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            } else {
5164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                // should not happen!
5176c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee                ALOGW("client %lld cache status inconsitent!", (long long)mConnectionId);
5184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            }
5194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        mReleasing.mReleasedIds.clear();
5214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return true;
5224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return false;
5244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
526da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee// should have mCache.mLock
527da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Leevoid BufferPoolClient::Impl::evictCaches(bool clearCache) {
528da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    int64_t now = getTimestampNow();
529da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    if (now >= mLastEvictCacheUs + kCacheTtlUs || clearCache) {
530da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        size_t evicted = 0;
531da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
532da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            if (!it->second->hasCache() && (it->second->expire() || clearCache)) {
533da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                it = mCache.mBuffers.erase(it);
534da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                ++evicted;
535da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            } else {
536da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee                ++it;
537da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee            }
538da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        }
539da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
540da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee              (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
541da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        mLastEvictCacheUs = now;
542da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    }
543da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee}
544da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
5454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::Impl::allocateBufferHandle(
5464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t>& params, BufferId *bufferId,
5474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        native_handle_t** handle) {
5484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLocalConnection) {
5494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const native_handle_t* allocHandle = NULL;
5504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ResultStatus status = mLocalConnection->allocate(
5514344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                params, bufferId, &allocHandle);
5524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        if (status == ResultStatus::OK) {
5534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            *handle = native_handle_clone(allocHandle);
5544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        }
5556c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee        ALOGV("client allocate result %lld %d : %u clone %p",
5566c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee              (long long)mConnectionId, status == ResultStatus::OK,
5574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim              *handle ? *bufferId : 0 , *handle);
5584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return status;
5594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
5614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::Impl::fetchBufferHandle(
5644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TransactionId transactionId, BufferId bufferId,
5654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        native_handle_t **handle) {
5664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    sp<IConnection> connection;
5674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (mLocal) {
5684344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        connection = mLocalConnection;
5694344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    } else {
5704344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        connection = mRemoteConnection;
5714344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
5724344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    ResultStatus status;
5730b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    Return<void> transResult = connection->fetch(
5744344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            transactionId, bufferId,
5754344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            [&status, &handle]
5764344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            (ResultStatus outStatus, Buffer outBuffer) {
5774344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                status = outStatus;
5784344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                if (status == ResultStatus::OK) {
5794344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                    *handle = native_handle_clone(
5804344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                            outBuffer.buffer.getNativeHandle());
5814344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                }
5824344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim            });
5830b17b87df67fa10759c5387b6538285d4a2b81acSungtak Lee    return transResult.isOk() ? status : ResultStatus::CRITICAL_ERROR;
5844344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5854344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5864344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5874344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimBufferPoolClient::BufferPoolClient(const sp<Accessor> &accessor) {
5884344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mImpl = std::make_shared<Impl>(accessor);
5894344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5904344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5914344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimBufferPoolClient::BufferPoolClient(const sp<IAccessor> &accessor) {
5924344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    mImpl = std::make_shared<Impl>(accessor);
5934344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5944344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5954344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimBufferPoolClient::~BufferPoolClient() {
5964344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    // TODO: how to handle orphaned buffers?
5974344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
5984344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
5994344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kimbool BufferPoolClient::isValid() {
6004344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return mImpl && mImpl->isValid();
6014344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6024344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
60371252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Leebool BufferPoolClient::isLocal() {
60471252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee    return mImpl && mImpl->isLocal();
60571252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee}
60671252fe064fc9329030ed7e612db3ae1761c8e0dSungtak Lee
607da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Leebool BufferPoolClient::isActive(int64_t *lastTransactionUs, bool clearCache) {
608da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    if (!isValid()) {
609da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        *lastTransactionUs = 0;
610da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee        return false;
611da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    }
612da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee    return mImpl->isActive(lastTransactionUs, clearCache);
613da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee}
614da9d245365644c12eaa95b4c043cc7e357cdf7d7Sungtak Lee
6154344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimConnectionId BufferPoolClient::getConnectionId() {
6164344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isValid()) {
6174344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return mImpl->getConnectionId();
6184344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6194344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return -1;
6204344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6214344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6224344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::getAccessor(sp<IAccessor> *accessor) {
6234344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isValid()) {
6244344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        *accessor = mImpl->getAccessor();
6254344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return ResultStatus::OK;
6264344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6274344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
6284344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6294344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6304344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::allocate(
6314344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        const std::vector<uint8_t> &params,
63238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t **handle,
6336c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee        std::shared_ptr<BufferPoolData> *buffer) {
6344344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isValid()) {
63538a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        return mImpl->allocate(params, handle, buffer);
6364344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6374344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
6384344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6394344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6404344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::receive(
6414344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
64238a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
6434344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isValid()) {
64438a50ccb2fac6c65d252fb4088b7dfac54c2fd37Sungtak Lee        return mImpl->receive(transactionId, bufferId, timestampUs, handle, buffer);
6454344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6464344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
6474344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6484344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6494344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik KimResultStatus BufferPoolClient::postSend(
6504344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        ConnectionId receiverId,
6516c65f54ce728454162b5bafc100aec023fcac6e1Sungtak Lee        const std::shared_ptr<BufferPoolData> &buffer,
6524344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        TransactionId *transactionId,
6534344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        int64_t *timestampUs) {
6544344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    if (isValid()) {
6554344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        bool result = mImpl->postSend(
6564344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim                buffer->mId, receiverId, transactionId, timestampUs);
6574344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim        return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
6584344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    }
6594344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim    return ResultStatus::CRITICAL_ERROR;
6604344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}
6614344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim
6624344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace implementation
6634344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace V1_0
6644344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace bufferpool
6654344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace media
6664344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace hardware
6674344f091aebaf3aee3ff062a95a05273bd2b1c57Wonsik Kim}  // namespace android
668