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