1 /*
2 * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3 * This file contains confidential and proprietary information of
4 * OSWare Technology Co., Ltd
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "hdi_drm_layer.h"
20 #include <cinttypes>
21 #include <cerrno>
22 #include "drm_device.h"
23
24 namespace OHOS {
25 namespace HDI {
26 namespace DISPLAY {
DrmGemBuffer(int drmfd,HdiLayerBuffer & hdl)27 DrmGemBuffer::DrmGemBuffer(int drmfd, HdiLayerBuffer &hdl) : mDrmFd(drmfd)
28 {
29 DISPLAY_LOGD();
30 Init(mDrmFd, hdl);
31 }
32
Init(int drmFd,HdiLayerBuffer & hdl)33 void DrmGemBuffer::Init(int drmFd, HdiLayerBuffer &hdl)
34 {
35 int ret;
36 const int MAX_COUNT = 4;
37 uint32_t pitches[MAX_COUNT] = {0};
38 uint32_t gemHandles[MAX_COUNT] = {0};
39 uint32_t offsets[MAX_COUNT] = {0};
40 DISPLAY_LOGD("hdl %{public}" PRIx64 "", hdl.GetMemHandle());
41 DISPLAY_CHK_RETURN_NOT_VALUE((drmFd < 0), DISPLAY_LOGE("can not init drmfd %{public}d", drmFd));
42 mDrmFormat = DrmDevice::ConvertToDrmFormat(static_cast<PixelFormat>(hdl.GetFormat()));
43 ret = drmPrimeFDToHandle(drmFd, hdl.GetFb(), &mGemHandle);
44 DISPLAY_CHK_RETURN_NOT_VALUE((ret != 0), DISPLAY_LOGE("can not get handle errno %{public}d", errno));
45
46 pitches[0] = hdl.GetStride();
47 gemHandles[0] = mGemHandle;
48 offsets[0] = 0;
49 ret = drmModeAddFB2(drmFd, hdl.GetWidth(), hdl.GetHeight(), mDrmFormat, gemHandles, pitches, offsets, &mFdId, 0);
50 DISPLAY_LOGD("mGemHandle %{public}d mFdId %{public}d", mGemHandle, mFdId);
51 DISPLAY_LOGD("w: %{public}d h: %{public}d mDrmFormat : %{public}d gemHandles: %{public}d pitches: %{public}d "
52 "offsets: %{public}d",
53 hdl.GetWidth(), hdl.GetHeight(), mDrmFormat, gemHandles[0], pitches[0], offsets[0]);
54 DISPLAY_CHK_RETURN_NOT_VALUE((ret != 0), DISPLAY_LOGE("can not add fb errno %{public}d", errno));
55 }
56
~DrmGemBuffer()57 DrmGemBuffer::~DrmGemBuffer()
58 {
59 DISPLAY_LOGD();
60 if (mFdId) {
61 if (drmModeRmFB(mDrmFd, mFdId)) {
62 DISPLAY_LOGE("can not free fdid %{public}d errno %{public}d", mFdId, errno);
63 }
64 }
65
66 if (mGemHandle) {
67 struct drm_gem_close gemClose = { 0 };
68 gemClose.handle = mGemHandle;
69 if (drmIoctl(mDrmFd, DRM_IOCTL_GEM_CLOSE, &gemClose)) {
70 DISPLAY_LOGE("can not free gem handle %{public}d errno : %{public}d", mGemHandle, errno);
71 }
72 }
73 }
74
IsValid()75 bool DrmGemBuffer::IsValid()
76 {
77 DISPLAY_LOGD();
78 return (mGemHandle != INVALID_DRM_ID) && (mFdId != INVALID_DRM_ID);
79 }
80
GetGemBuffer()81 DrmGemBuffer *HdiDrmLayer::GetGemBuffer()
82 {
83 DISPLAY_LOGD();
84 std::unique_ptr<DrmGemBuffer> ptr = std::make_unique<DrmGemBuffer>(DrmDevice::GetDrmFd(), *GetCurrentBuffer());
85 lastBuffer_ = std::move(mCurrentBuffer);
86 mCurrentBuffer = std::move(ptr);
87 return mCurrentBuffer.get();
88 }
89 } // namespace OHOS
90 } // namespace HDI
91 } // namespace DISPLAY
92