• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_composition.h"
20 #include <cerrno>
21 #include "hdi_drm_layer.h"
22 
23 namespace OHOS {
24 namespace HDI {
25 namespace DISPLAY {
HdiDrmComposition(std::shared_ptr<DrmConnector> & connector,std::shared_ptr<DrmCrtc> & crtc,std::shared_ptr<DrmDevice> & drmDevice)26 HdiDrmComposition::HdiDrmComposition(std::shared_ptr<DrmConnector> &connector, std::shared_ptr<DrmCrtc> &crtc,
27     std::shared_ptr<DrmDevice> &drmDevice)
28     : mDrmDevice(drmDevice), mConnector(connector), mCrtc(crtc)
29 {
30     DISPLAY_LOGD();
31 }
32 
Init()33 int32_t HdiDrmComposition::Init()
34 {
35     DISPLAY_LOGD();
36     mPrimPlanes.clear();
37     mOverlayPlanes.clear();
38     mPlanes.clear();
39     DISPLAY_CHK_RETURN((mCrtc == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("crtc is null"));
40     DISPLAY_CHK_RETURN((mConnector == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("connector is null"));
41     DISPLAY_CHK_RETURN((mDrmDevice == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("drmDevice is null"));
42     mPrimPlanes = mDrmDevice->GetDrmPlane(mCrtc->GetPipe(), DRM_PLANE_TYPE_PRIMARY);
43     mOverlayPlanes = mDrmDevice->GetDrmPlane(mCrtc->GetPipe(), DRM_PLANE_TYPE_OVERLAY);
44     DISPLAY_CHK_RETURN((mPrimPlanes.size() == 0), DISPLAY_FAILURE, DISPLAY_LOGE("has no primary plane"));
45     mPlanes.insert(mPlanes.end(), mPrimPlanes.begin(), mPrimPlanes.end());
46     mPlanes.insert(mPlanes.end(), mOverlayPlanes.begin(), mOverlayPlanes.end());
47     return DISPLAY_SUCCESS;
48 }
49 
SetLayers(std::vector<HdiLayer * > & layers,HdiLayer & clientLayer)50 int32_t HdiDrmComposition::SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer)
51 {
52     // now we do not surpport present direct
53     DISPLAY_LOGD();
54     mCompLayers.clear();
55     mCompLayers.push_back(&clientLayer);
56     return DISPLAY_SUCCESS;
57 }
58 
ApplyPlane(HdiDrmLayer & layer,DrmPlane & drmPlane,drmModeAtomicReqPtr pset)59 int32_t HdiDrmComposition::ApplyPlane(HdiDrmLayer &layer, DrmPlane &drmPlane, drmModeAtomicReqPtr pset)
60 {
61     // set fence in
62     int ret;
63     int fenceFd = layer.GetAcquireFenceFd();
64     int propId = drmPlane.GetPropFenceInId();
65     DISPLAY_LOGD();
66     if (propId != 0) {
67         DISPLAY_LOGD("set the fence in prop");
68         if (fenceFd >= 0) {
69             ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), propId, fenceFd);
70             DISPLAY_LOGD("set the IfenceProp plane id %{public}d, propId %{public}d, fenceFd %{public}d",
71                 drmPlane.GetId(), propId, fenceFd);
72             DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set IN_FENCE_FD failed"));
73         }
74     }
75 
76     // set fb id
77     DrmGemBuffer *gemBuffer = layer.GetGemBuffer();
78     DISPLAY_CHK_RETURN((gemBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("current gemBuffer is nullptr"));
79     DISPLAY_CHK_RETURN((!gemBuffer->IsValid()), DISPLAY_FAILURE, DISPLAY_LOGE("the DrmGemBuffer is invalid"));
80     ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropFbId(), gemBuffer->GetFbId());
81     DISPLAY_LOGD("set the fb planeid %{public}d, propId %{public}d, fbId %{public}d", drmPlane.GetId(),
82         drmPlane.GetPropFbId(), gemBuffer->GetFbId());
83     DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set fb id fialed errno : %{public}d", errno));
84 
85     // set crtc id
86     ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtcId(), mCrtc->GetId());
87     DISPLAY_LOGD("set the crtc planeId %{public}d, propId %{public}d, crtcId %{public}d", drmPlane.GetId(),
88         drmPlane.GetPropCrtcId(), mCrtc->GetId());
89     DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set crtc id fialed errno : %{public}d", errno));
90     return DISPLAY_SUCCESS;
91 }
92 
UpdateMode(std::unique_ptr<DrmModeBlock> & modeBlock,drmModeAtomicReq & pset)93 int32_t HdiDrmComposition::UpdateMode(std::unique_ptr<DrmModeBlock> &modeBlock, drmModeAtomicReq &pset)
94 {
95     // set the mode
96     int ret;
97     DISPLAY_LOGD();
98     if (mCrtc->NeedModeSet()) {
99         modeBlock = mConnector->GetModeBlockFromId(mCrtc->GetActiveModeId());
100         if ((modeBlock != nullptr) && (modeBlock->GetBlockId() != DRM_INVALID_ID)) {
101             // set to active
102             DISPLAY_LOGD("set crtc to active");
103             ret = drmModeAtomicAddProperty(&pset, mCrtc->GetId(), mCrtc->GetActivePropId(), 1);
104             DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
105                 DISPLAY_LOGE("can not add the active prop errno %{public}d", errno));
106 
107             // set the mode id
108             DISPLAY_LOGD("set the mode");
109             ret = drmModeAtomicAddProperty(&pset, mCrtc->GetId(), mCrtc->GetModePropId(), modeBlock->GetBlockId());
110             DISPLAY_LOGD("set the mode planeId %{public}d, propId %{public}d, GetBlockId: %{public}d", mCrtc->GetId(),
111                 mCrtc->GetModePropId(), modeBlock->GetBlockId());
112             DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
113                 DISPLAY_LOGE("can not add the mode prop errno %{public}d", errno));
114             ret = drmModeAtomicAddProperty(&pset, mConnector->GetId(), mConnector->GetPropCrtcId(), mCrtc->GetId());
115             DISPLAY_LOGD("set the connector id: %{public}d, propId %{public}d, crtcId %{public}d", mConnector->GetId(),
116                 mConnector->GetPropCrtcId(), mCrtc->GetId());
117             DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
118                 DISPLAY_LOGE("can not add the crtc id prop %{public}d", errno));
119         }
120     }
121     return DISPLAY_SUCCESS;
122 }
123 
Apply(bool modeSet)124 int32_t HdiDrmComposition::Apply(bool modeSet)
125 {
126     uint64_t crtcOutFence = -1;
127     int ret;
128     std::unique_ptr<DrmModeBlock> modeBlock;
129     int drmFd = mDrmDevice->GetDrmFd();
130     DISPLAY_LOGD();
131     DISPLAY_CHK_RETURN((mPlanes.size() < mCompLayers.size()), DISPLAY_FAILURE, DISPLAY_LOGE("plane not enough"));
132     drmModeAtomicReqPtr pset = drmModeAtomicAlloc();
133     DISPLAY_CHK_RETURN((pset == nullptr), DISPLAY_NULL_PTR,
134         DISPLAY_LOGE("drm atomic alloc failed errno %{public}d", errno));
135     AtomicReqPtr atomicReqPtr = AtomicReqPtr(pset);
136 
137     // set the outFence property
138     ret = drmModeAtomicAddProperty(atomicReqPtr.Get(), mCrtc->GetId(), mCrtc->GetOutFencePropId(),
139         (uint64_t)&crtcOutFence);
140 
141     DISPLAY_LOGD("Apply Set OutFence crtc id: %{public}d, fencePropId %{public}d", mCrtc->GetId(),
142         mCrtc->GetOutFencePropId());
143     DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the outfence property of crtc failed "));
144 
145     // set the plane info.
146     DISPLAY_LOGD("mCompLayers size %{public}zd", mCompLayers.size());
147     for (uint32_t i = 0; i < mCompLayers.size(); i++) {
148         HdiDrmLayer *layer = static_cast<HdiDrmLayer *>(mCompLayers[i]);
149         auto &drmPlane = mPlanes[i];
150         ret = ApplyPlane(*layer, *drmPlane, atomicReqPtr.Get());
151         if (ret != DISPLAY_SUCCESS) {
152             DISPLAY_LOGE("apply plane failed");
153             break;
154         }
155     }
156     ret = UpdateMode(modeBlock, *(atomicReqPtr.Get()));
157     DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("update mode failed"));
158     uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
159 
160     ret = drmModeAtomicCommit(drmFd, atomicReqPtr.Get(), flags, nullptr);
161     DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE,
162         DISPLAY_LOGE("drmModeAtomicCommit failed %{public}d errno %{public}d", ret, errno));
163     // set the release fence
164     for (auto layer : mCompLayers) {
165         layer->SetReleaseFence(dup(static_cast<int32_t>(crtcOutFence)));
166     }
167     close(static_cast<int32_t>(crtcOutFence));
168     crtcOutFence = -1;
169     return DISPLAY_SUCCESS;
170 }
171 } // OHOS
172 } // HDI
173 } // DISPLAY
174