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