1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef OHOS_HDI_DISPLAY_V1_0_BUFFER_CACHE_UTILS_H
17#define OHOS_HDI_DISPLAY_V1_0_BUFFER_CACHE_UTILS_H
18
19#include <functional>
20#include <memory>
21#include <unordered_map>
22#include "base/native_buffer.h"
23#include "cache_manager.h"
24#include "common/include/display_interface_utils.h"
25#include "hdf_log.h"
26
27namespace OHOS {
28namespace HDI {
29namespace Display {
30namespace Composer {
31
32#define DEBUG_BUFFER_CACHE_UTILS
33class BufferCacheUtils {
34public:
35    static BufferHandle* NativeBufferCache(const std::shared_ptr<CacheManager<uint32_t, NativeBuffer>>& cacheMgr,
36        BufferHandle* buffer, uint32_t seqNo, uint32_t callerId, bool &needFreeBuffer)
37    {
38        BufferHandle* handle = nullptr;
39        needFreeBuffer = false;
40        if (buffer == nullptr && seqNo != UINT32_MAX) {
41            // Fetch buffer from caches indexed by seqNo
42            NativeBuffer* nativeBuffer = cacheMgr->SearchCache(seqNo);
43            DISPLAY_CHK_RETURN(nativeBuffer == nullptr, handle,
44                HDF_LOGE("%{public}s: Get Native buffer cache is not found, callerId=%{public}u, seqNo=%{public}u",
45                    __func__, callerId, seqNo));
46
47            handle = nativeBuffer->GetBufferHandle();
48            HDF_LOGD("apply %{public}s: callerId=%{public}u, seqNo=%{public}u", __func__, callerId, seqNo);
49            DISPLAY_CHK_RETURN(handle == nullptr, handle,
50                HDF_LOGE("%{public}s: Get buffer cache is nullptr, callerId=%{public}u, seqNo=%{public}u",
51                    __func__, callerId, seqNo));
52        } else if (buffer != nullptr && seqNo != UINT32_MAX) {
53            // Insert buffer to caches
54            NativeBuffer* nativeBuffer = new NativeBuffer();
55            DISPLAY_CHK_RETURN(nativeBuffer == nullptr, nullptr,
56                HDF_LOGE("%{public}s: new nativeBuffer fail", __func__));
57            nativeBuffer->SetBufferHandle(buffer, true, nullptr);
58
59            auto retBool = cacheMgr->InsertCache(seqNo, nativeBuffer);
60            if (retBool == false) {
61                // if InsertCache failed, remove BufferHandle ownership
62                handle = nativeBuffer->Move();
63                delete nativeBuffer;
64                HDF_LOGE("%{public}s: Set buffer cache fail, callerId=%{public}u, seqNo=%{public}u",
65                    __func__, callerId, seqNo);
66                needFreeBuffer = true;
67            } else {
68                handle = buffer;
69            }
70            HDF_LOGD("insert %{public}s: callerId=%{public}u, seqNo=%{public}u", __func__, callerId, seqNo);
71        } else if (buffer != nullptr && seqNo == UINT32_MAX) {
72            // Caches not used
73            HDF_LOGI("%{public}s: buffer cache passthrough", __func__);
74            handle = buffer;
75            needFreeBuffer = true;
76        } else {
77            // Input arguments error
78            DISPLAY_CHK_RETURN(((buffer == nullptr)), nullptr,
79                HDF_LOGE("%{public}s: Inputs args check error", __func__));
80        }
81
82        return handle;
83    }
84};
85} // namespace Composer
86} // namespace Display
87} // namespace HDI
88} // namespace OHOS
89#endif // OHOS_HDI_DISPLAY_V1_0_BUFFER_CACHE_UTILS_H
90