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