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_layer.h"
17 #include <cerrno>
18 #include <fstream>
19 #include <libsync.h>
20 #include <securec.h>
21 #include <sstream>
22 #include <string>
23 #include <sys/time.h>
24 #include <unistd.h>
25 #include "display_buffer_vdi_impl.h"
26 #include "v1_0/display_composer_type.h"
27
28 namespace OHOS {
29 namespace HDI {
30 namespace DISPLAY {
31 uint32_t HdiLayer::mIdleId = 0;
32 std::unordered_set<uint32_t> HdiLayer::mIdSets;
33 std::shared_ptr<IDisplayBufferVdi> g_buffer;
34 constexpr int TIME_BUFFER_MAX_LEN = 15;
35 constexpr int FILE_NAME_MAX_LEN = 80;
36 const std::string PATH_PREFIX = "/data/local/traces/";
37
HdiLayerBuffer(const BufferHandle & hdl)38 HdiLayerBuffer::HdiLayerBuffer(const BufferHandle &hdl)
39 : mPhyAddr(hdl.phyAddr), mHeight(hdl.height), mWidth(hdl.width), mStride(hdl.stride), mFormat(hdl.format)
40 {
41 DISPLAY_LOGD();
42 mFd = dup(hdl.fd);
43 mHandle = hdl;
44 if (mFd < 0) {
45 DISPLAY_LOGE("the fd : %{public}d dup failed errno %{public}d", hdl.fd, errno);
46 }
47 }
48
~HdiLayerBuffer()49 HdiLayerBuffer::~HdiLayerBuffer()
50 {
51 DISPLAY_LOGD();
52 if (mFd >= 0) {
53 close(mFd);
54 }
55 }
56
operator =(const BufferHandle & right)57 HdiLayerBuffer &HdiLayerBuffer::operator = (const BufferHandle &right)
58 {
59 DISPLAY_LOGD();
60 if (mFd >= 0) {
61 close(mFd);
62 }
63 mFd = dup(right.fd);
64 mPhyAddr = right.phyAddr;
65 mWidth = right.width;
66 mHeight = right.height;
67 mStride = right.stride;
68 mFormat = right.format;
69 return *this;
70 }
71
GetIdleId()72 uint32_t HdiLayer::GetIdleId()
73 {
74 const uint32_t oldIdleId = mIdleId;
75 uint32_t id = 0xffffffff;
76 // ensure the mIdleId not 0xffffffff
77 mIdleId = mIdleId % 0xffffffff;
78 do {
79 auto iter = mIdSets.find(mIdleId);
80 if (iter == mIdSets.end()) {
81 id = mIdleId;
82 break;
83 }
84 mIdleId = (mIdleId + 1) % 0xffffffff;
85 } while (oldIdleId != mIdleId);
86 mIdSets.emplace(id);
87 mIdleId++;
88 DISPLAY_LOGD("id %{public}d mIdleId %{public}d", id, mIdleId);
89 return id;
90 }
91
Init()92 int32_t HdiLayer::Init()
93 {
94 DISPLAY_LOGD();
95 uint32_t id = GetIdleId();
96 DISPLAY_CHK_RETURN((id == 0xffffffff), DISPLAY_FAILURE, DISPLAY_LOGE("have no id to used"));
97 mId = id;
98 return DISPLAY_SUCCESS;
99 }
100
SetLayerRegion(IRect * rect)101 int32_t HdiLayer::SetLayerRegion(IRect *rect)
102 {
103 DISPLAY_CHK_RETURN((rect == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in rect is nullptr"));
104 DISPLAY_LOGD(" displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d", rect->x, rect->y, rect->w,
105 rect->h);
106 mDisplayRect = *rect;
107 return DISPLAY_SUCCESS;
108 }
109
SetLayerCrop(IRect * rect)110 int32_t HdiLayer::SetLayerCrop(IRect *rect)
111 {
112 DISPLAY_CHK_RETURN((rect == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in rect is nullptr"));
113 DISPLAY_LOGD("id : %{public}d crop x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId, rect->x,
114 rect->y, rect->w, rect->h);
115 mCrop = *rect;
116 return DISPLAY_SUCCESS;
117 }
118
SetLayerZorder(uint32_t zorder)119 void HdiLayer::SetLayerZorder(uint32_t zorder)
120 {
121 DISPLAY_LOGD("id : %{public}d zorder : %{public}d ", mId, zorder);
122 mZorder = zorder;
123 }
124
SetLayerPreMulti(bool preMul)125 int32_t HdiLayer::SetLayerPreMulti(bool preMul)
126 {
127 DISPLAY_LOGD();
128 mPreMul = preMul;
129 return DISPLAY_SUCCESS;
130 }
131
SetLayerAlpha(LayerAlpha * alpha)132 int32_t HdiLayer::SetLayerAlpha(LayerAlpha *alpha)
133 {
134 DISPLAY_CHK_RETURN((alpha == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in alpha is nullptr"));
135 DISPLAY_LOGD("enable alpha %{public}d galpha 0x%{public}x", alpha->enGlobalAlpha, alpha->gAlpha);
136 mAlpha = *alpha;
137 return DISPLAY_SUCCESS;
138 }
139
SetLayerTransformMode(TransformType type)140 int32_t HdiLayer::SetLayerTransformMode(TransformType type)
141 {
142 DISPLAY_LOGD("TransformType %{public}d", type);
143 mTransformType = type;
144 return DISPLAY_SUCCESS;
145 }
146
SetLayerDirtyRegion(IRect * region)147 int32_t HdiLayer::SetLayerDirtyRegion(IRect *region)
148 {
149 DISPLAY_CHK_RETURN((region == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the in rect is null"));
150 DISPLAY_LOGD("id : %{public}d DirtyRegion x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId,
151 region->x, region->y, region->w, region->h);
152 return DISPLAY_SUCCESS;
153 }
154
SetLayerVisibleRegion(uint32_t num,IRect * rect)155 int32_t HdiLayer::SetLayerVisibleRegion(uint32_t num, IRect *rect)
156 {
157 DISPLAY_LOGD("id : %{public}d DirtyRegion x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId, rect->x,
158 rect->y, rect->w, rect->h);
159 return DISPLAY_SUCCESS;
160 }
161
SetLayerBuffer(const BufferHandle * buffer,int32_t fence)162 int32_t HdiLayer::SetLayerBuffer(const BufferHandle *buffer, int32_t fence)
163 {
164 DISPLAY_LOGD();
165 DISPLAY_CHK_RETURN((buffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("buffer is nullptr"));
166 std::unique_ptr<HdiLayerBuffer> layerbuffer = std::make_unique<HdiLayerBuffer>(*buffer);
167 mHdiBuffer = std::move(layerbuffer);
168 if (fence > -1) {
169 mAcquireFence = dup(fence);
170 }
171 return DISPLAY_SUCCESS;
172 }
173
SetLayerCompositionType(CompositionType type)174 int32_t HdiLayer::SetLayerCompositionType(CompositionType type)
175 {
176 DISPLAY_LOGD("CompositionType type %{public}d", type);
177 mCompositionType = type;
178 return DISPLAY_SUCCESS;
179 }
180
SetLayerBlendType(BlendType type)181 int32_t HdiLayer::SetLayerBlendType(BlendType type)
182 {
183 DISPLAY_LOGD("BlendType type %{public}d", type);
184 mBlendType = type;
185 return DISPLAY_SUCCESS;
186 }
187
SetLayerVisible(bool visible)188 int32_t HdiLayer::SetLayerVisible(bool visible)
189 {
190 DISPLAY_LOGD("SetLayerVisible type %{public}d", visible);
191 mVisible = visible;
192 return DISPLAY_SUCCESS;
193 }
194
SetPixel(const BufferHandle & handle,int x,int y,uint32_t color)195 void HdiLayer::SetPixel(const BufferHandle &handle, int x, int y, uint32_t color)
196 {
197 const int32_t pixelBytes = 4;
198 const int32_t bpp = 32;
199 DISPLAY_CHK_RETURN_NOT_VALUE((bpp <= 0),
200 DISPLAY_LOGE("CheckPixel do not support format %{public}d", handle.format));
201 DISPLAY_CHK_RETURN_NOT_VALUE((handle.virAddr == nullptr), DISPLAY_LOGE("CheckPixel viraddr is null must map it"));
202 DISPLAY_CHK_RETURN_NOT_VALUE((x < 0 || x >= handle.width),
203 DISPLAY_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
204 DISPLAY_CHK_RETURN_NOT_VALUE((y < 0 || y >= handle.height),
205 DISPLAY_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
206 int32_t position = y * handle.width + x;
207 if ((position * pixelBytes) > handle.size) {
208 DISPLAY_LOGE("the pixel postion outside\n");
209 }
210 uint32_t *pixel = reinterpret_cast<uint32_t *>(handle.virAddr) + position;
211 *pixel = color;
212 }
213
ClearColor(uint32_t color)214 void HdiLayer::ClearColor(uint32_t color)
215 {
216 DISPLAY_LOGD();
217 BufferHandle &handle = mHdiBuffer->mHandle;
218 for (int32_t x = 0; x < handle.width; x++) {
219 for (int32_t y = 0; y < handle.height; y++) {
220 SetPixel(handle, x, y, color);
221 }
222 }
223 }
224
WaitAcquireFence()225 void HdiLayer::WaitAcquireFence()
226 {
227 int fd = GetAcquireFenceFd();
228 if (fd < 0) {
229 DISPLAY_LOGE("fd is invalid");
230 return;
231 }
232 sync_wait(fd, mFenceTimeOut);
233 }
234 } // namespace OHOS
235 } // namespace HDI
236 } // namespace DISPLAY
237