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#include "hdi_test_layer.h"
17#include <unistd.h>
18#include "hdi_test_device.h"
19#include "v1_0/include/idisplay_buffer.h"
20#include "v1_0/display_buffer_type.h"
21#include "v1_2/display_composer_type.h"
22
23namespace OHOS {
24namespace HDI {
25namespace Display {
26namespace TEST {
27using namespace OHOS::HDI::Display::Buffer::V1_0;
28using namespace OHOS::HDI::Display::Composer::V1_2;
29
30HdiGrallocBuffer::HdiGrallocBuffer(uint32_t seqNo, uint32_t w, uint32_t h, Composer::V1_0::PixelFormat fmt)
31{
32    std::shared_ptr<IDisplayBuffer> gralloc = HdiTestDevice::GetInstance().GetGrallocInterface();
33    AllocInfo info = { 0 };
34    info.width = w;
35    info.height = h;
36    info.usage = Composer::V1_2::HBM_USE_MEM_DMA | Composer::V1_2::HBM_USE_CPU_READ |
37                 Composer::V1_2::HBM_USE_CPU_WRITE;
38    info.format = fmt;
39
40    BufferHandle* buffer = nullptr;
41    int ret = gralloc->AllocMem(info, buffer);
42    if (ret != DISPLAY_SUCCESS) {
43        DISPLAY_TEST_LOGE("can not alloc memory");
44    }
45    if (buffer != nullptr) {
46        void* vaddr = gralloc->Mmap(*buffer);
47        if (vaddr == nullptr) {
48            DISPLAY_TEST_LOGE("mmap failed");
49        }
50        buffer_ = buffer;
51        seqNo_ = seqNo;
52    }
53}
54
55HdiGrallocBuffer::~HdiGrallocBuffer()
56{
57    if (buffer_ != nullptr) {
58        std::shared_ptr<IDisplayBuffer> gralloc = HdiTestDevice::GetInstance().GetGrallocInterface();
59        if (buffer_->virAddr != nullptr) {
60            int ret = gralloc->Unmap(*buffer_);
61            if (ret != DISPLAY_SUCCESS) {
62                DISPLAY_TEST_LOGE("can not ummap buffer handle");
63            }
64        }
65        gralloc->FreeMem(*buffer_);
66        buffer_ = nullptr;
67    }
68    if (mReleaseFence != -1) {
69        close(mReleaseFence);
70    }
71}
72
73void HdiGrallocBuffer::SetReleaseFence(int fd)
74{
75    DISPLAY_TEST_LOGD("the fd is %{public}d", fd);
76    if (mReleaseFence != -1) {
77        close(mReleaseFence);
78        mReleaseFence = -1;
79    }
80}
81
82void HdiGrallocBuffer::SetAcquirceFence(int fd)
83{
84    DISPLAY_TEST_LOGD("the fd is %{public}d", fd);
85    mAcquireFence = fd;
86}
87
88int32_t HdiGrallocBuffer::SetGraphicBuffer(std::function<int32_t (const BufferHandle*, uint32_t)> realFunc)
89{
90    DISPLAY_TEST_CHK_RETURN(buffer_ == nullptr, DISPLAY_FAILURE,
91        DISPLAY_TEST_LOGE("buffer handle is null"));
92    DISPLAY_TEST_CHK_RETURN(seqNo_ == UINT32_MAX, DISPLAY_FAILURE,
93        DISPLAY_TEST_LOGE("seqNo is invalid"));
94
95    int32_t ret = DISPLAY_SUCCESS;
96    if (cacheValid_ == false) {
97        ret = realFunc(buffer_, seqNo_);
98        cacheValid_ = (ret == DISPLAY_SUCCESS) ? true : false;
99    } else {
100        ret = realFunc(nullptr, seqNo_);
101    }
102    return ret;
103}
104
105HdiGrallocBuffer* HdiTestLayer::AcquireBackBuffer()
106{
107    if (!backBuffers_.empty()) {
108        if (currentBuffer_ != nullptr) {
109            frontBuffers_.emplace(std::move(currentBuffer_));
110        }
111        currentBuffer_ = std::move(backBuffers_.front());
112        backBuffers_.pop();
113    }
114    return currentBuffer_.get();
115}
116
117HdiGrallocBuffer* HdiTestLayer::GetFrontBuffer() const
118{
119    HdiGrallocBuffer* buffer = nullptr;
120    if (!frontBuffers_.empty()) {
121        buffer = frontBuffers_.front().get();
122    }
123    return buffer;
124}
125
126HdiGrallocBuffer* HdiTestLayer::GetBackBuffer() const
127{
128    HdiGrallocBuffer* buffer = nullptr;
129    if (!backBuffers_.empty()) {
130        buffer = backBuffers_.front().get();
131    }
132    return buffer;
133}
134
135HdiTestLayer::HdiTestLayer(LayerInfo& info, uint32_t id, uint32_t displayId)
136    : id_(id), displayID_(displayId), layerBufferCount_(MAX_BUFFER_COUNT), layerInfo_(info)
137{}
138
139static uint32_t GenerateSeq()
140{
141    static uint32_t originSeq = 0;
142    return originSeq++;
143}
144
145int32_t HdiTestLayer::Init(uint32_t bufferCount)
146{
147    // init the font queue
148    DISPLAY_TEST_LOGD();
149    layerBufferCount_ = bufferCount;
150    for (uint32_t i = 0; i < layerBufferCount_; i++) {
151        std::unique_ptr<HdiGrallocBuffer> buffer =
152            std::make_unique<HdiGrallocBuffer>(GenerateSeq(),
153            layerInfo_.width, layerInfo_.height, layerInfo_.pixFormat);
154        DISPLAY_TEST_CHK_RETURN((buffer->Get() == nullptr), DISPLAY_FAILURE,
155            DISPLAY_TEST_LOGE("buffer handle is null"));
156        frontBuffers_.emplace(std::move(buffer));
157    }
158    displayRect_.w = layerInfo_.width;
159    displayRect_.h = layerInfo_.height;
160    cropRect_ = displayRect_;
161    return DISPLAY_SUCCESS;
162}
163
164
165int32_t HdiTestLayer::SwapFrontToBackQ()
166{
167    DISPLAY_TEST_CHK_RETURN((frontBuffers_.empty()), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the font buffer is empty"));
168    backBuffers_.emplace(std::move(frontBuffers_.front()));
169    frontBuffers_.pop();
170    return DISPLAY_SUCCESS;
171}
172
173int32_t HdiTestLayer::SwapBackToFrontQ()
174{
175    DISPLAY_TEST_CHK_RETURN((backBuffers_.empty()), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the font buffer is empty"));
176    frontBuffers_.emplace(std::move(backBuffers_.front()));
177    backBuffers_.pop();
178    return DISPLAY_SUCCESS;
179}
180
181void HdiTestLayer::SetLayerPosition(const IRect& rect)
182{
183    DISPLAY_TEST_LOGD("x : %{public}d y : %{public}d w : %{public}d h : %{public}d", rect.x, rect.y, rect.w, rect.h);
184    displayRect_ = rect;
185}
186
187void HdiTestLayer::SetLayerCrop(const IRect& rect)
188{
189    DISPLAY_TEST_LOGD("x : %{public}d y : %{public}d w : %{public}d h : %{public}d", rect.x, rect.y, rect.w, rect.h);
190    cropRect_ = rect;
191}
192
193int32_t HdiTestLayer::PreparePresent()
194{
195    int ret;
196    DISPLAY_TEST_LOGD();
197    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerRegion(displayID_, id_, displayRect_);
198    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set display rect failed"));
199
200    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerCrop(displayID_, id_, cropRect_);
201    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set display crop failed"));
202
203    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerZorder(displayID_, id_, zorder_);
204    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set display zorder failed"));
205
206    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerCompositionType(displayID_, id_, compType_);
207    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
208        DISPLAY_TEST_LOGE("set display composition type failed"));
209
210    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerTransformMode(displayID_, id_, transform_);
211    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set transform mode failed"));
212
213    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerAlpha(displayID_, id_, alpha_);
214    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set alpha failed"));
215
216    HdiGrallocBuffer* buffer = AcquireBackBuffer();
217    DISPLAY_TEST_CHK_RETURN((buffer == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get back buffer"));
218
219    BufferHandle* handle = buffer->Get();
220    DISPLAY_TEST_CHK_RETURN((handle == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("BufferHandle is null"));
221
222    IRect tmp {0, 0, handle->width, handle->height};
223    std::vector<IRect> vRects;
224    vRects.push_back(tmp);
225    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerVisibleRegion(displayID_, id_, vRects);
226    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
227        DISPLAY_TEST_LOGE("SetLayerVisibleRegion failed"));
228
229    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerDirtyRegion(displayID_, id_, vRects);
230    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
231        DISPLAY_TEST_LOGE("SetLayerDirtyRegion failed"));
232
233    ret = buffer->SetGraphicBuffer([&](const BufferHandle* ptrBuffer, uint32_t seqNo) -> int32_t {
234        std::vector<uint32_t> deletingList;
235        int32_t result = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerBuffer(
236            displayID_, id_, ptrBuffer, seqNo, -1, deletingList);
237        DISPLAY_TEST_CHK_RETURN((result != DISPLAY_SUCCESS), DISPLAY_FAILURE,
238            DISPLAY_TEST_LOGE("set buffer handle failed"));
239        return DISPLAY_SUCCESS;
240    });
241    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), ret, DISPLAY_TEST_LOGE("set buffer handle failed"));
242
243    ret = HdiTestDevice::GetInstance().GetDeviceInterface()->SetLayerBlendType(displayID_, id_, blendType_);
244    DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set blend type failed"));
245    return DISPLAY_SUCCESS;
246}
247
248void HdiTestLayer::SetZorder(uint32_t zorder)
249{
250    DISPLAY_TEST_LOGD("the zorder is %{public}u", zorder);
251    zorder_ = zorder;
252}
253
254void HdiTestLayer::SetCompType(Composer::V1_0::CompositionType type)
255{
256    DISPLAY_TEST_LOGD("layer id %{public}u ,the type is : %{public}d", id_, type);
257    compType_ = type;
258}
259
260void HdiTestLayer::SetTransform(TransformType transform)
261{
262    transform_ = transform;
263}
264
265void HdiTestLayer::SetAlpha(LayerAlpha alpha)
266{
267    DISPLAY_TEST_LOGD();
268    alpha_ = alpha;
269}
270
271void HdiTestLayer::SetBlendType(BlendType type)
272{
273    DISPLAY_TEST_LOGD("type %{public}d", type);
274    blendType_ = type;
275}
276
277void HdiTestLayer::SetReleaseFence(int fd)
278{
279    DISPLAY_TEST_LOGD("layer id %{public}u , fd %{public}d", id_, fd);
280    if (currentBuffer_ != nullptr) {
281        currentBuffer_->SetReleaseFence(fd);
282    }
283}
284
285uint32_t HdiTestLayer::GetLayerBuffercount() const
286{
287    return layerBufferCount_;
288}
289
290HdiTestLayer::~HdiTestLayer() {}
291} // OHOS
292} // HDI
293} // Display
294} // TEST
295