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