• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 = INVALIDE_LAYER_ID;
76     // ensure the mIdleId not INVALIDE_LAYER_ID
77     mIdleId = mIdleId % INVALIDE_LAYER_ID;
78     do {
79         auto iter = mIdSets.find(mIdleId);
80         if (iter == mIdSets.end()) {
81             id = mIdleId;
82             break;
83         }
84         mIdleId = (mIdleId + 1) % INVALIDE_LAYER_ID;
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 == INVALIDE_LAYER_ID), 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,
105         rect->w, 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,
114         rect->x, 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,
158         rect->x, rect->y, rect->w, rect->h);
159     return DISPLAY_SUCCESS;
160 }
161 
GetFileName(char * fileName,uint32_t len,const BufferHandle * buffer)162 static int32_t GetFileName(char *fileName, uint32_t len, const BufferHandle *buffer)
163 {
164     struct timeval tv;
165     char nowStr[TIME_BUFFER_MAX_LEN] = {0};
166 
167     gettimeofday(&tv, nullptr);
168     if (strftime(nowStr, sizeof(nowStr), "%m-%d-%H-%M-%S", localtime(&tv.tv_sec)) == 0) {
169         DISPLAY_LOGE("strftime failed");
170         return DISPLAY_FAILURE;
171     };
172     int32_t ret = snprintf_s(fileName, len, len - 1, "hdi_layer_%s-%lld_%dx%d.img",
173         nowStr, tv.tv_usec, buffer->width, buffer->height);
174     DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("snprintf_s failed"));
175     return DISPLAY_SUCCESS;
176 }
177 
DumpLayerBuffer(BufferHandle * buffer)178 static int32_t DumpLayerBuffer(BufferHandle *buffer)
179 {
180     CHECK_NULLPOINTER_RETURN_VALUE(buffer, DISPLAY_NULL_PTR);
181 
182     int32_t ret = 0;
183     if (g_buffer== nullptr) {
184         IDisplayBufferVdi* dispBuf = new DisplayBufferVdiImpl();
185         DISPLAY_CHK_RETURN((dispBuf == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("dispBuf init failed"));
186         g_buffer.reset(dispBuf);
187     }
188 
189     char fileName[FILE_NAME_MAX_LEN] = {0};
190     ret = GetFileName(fileName, FILE_NAME_MAX_LEN, buffer);
191     DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("GetFileName failed"));
192     DISPLAY_LOGI("fileName = %{public}s", fileName);
193 
194     std::stringstream filePath;
195     filePath << PATH_PREFIX << fileName;
196     std::ofstream rawDataFile(filePath.str(), std::ofstream::binary);
197     DISPLAY_CHK_RETURN((!rawDataFile.good()), DISPLAY_FAILURE, DISPLAY_LOGE("open file failed, %{public}s",
198         std::strerror(errno)));
199 
200     void *buffAddr = g_buffer->Mmap(*buffer);
201     DISPLAY_CHK_RETURN((buffAddr == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("Mmap buffer failed"));
202 
203     rawDataFile.write(static_cast<const char *>(buffAddr), buffer->size);
204     rawDataFile.close();
205 
206     ret = g_buffer->Unmap(*buffer);
207     DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Unmap buffer failed"));
208     return DISPLAY_SUCCESS;
209 }
210 
SetLayerBuffer(const BufferHandle * buffer,int32_t fence)211 int32_t HdiLayer::SetLayerBuffer(const BufferHandle *buffer, int32_t fence)
212 {
213     DISPLAY_LOGD();
214     DISPLAY_CHK_RETURN((buffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("buffer is nullptr"));
215     std::unique_ptr<HdiLayerBuffer> layerbuffer = std::make_unique<HdiLayerBuffer>(*buffer);
216     mHdiBuffer = std::move(layerbuffer);
217     mAcquireFence = dup(fence);
218     if (access("/data/hdi_dump_layer", F_OK) != -1) {
219         if (DumpLayerBuffer(const_cast<BufferHandle *>(buffer)) != DISPLAY_SUCCESS) {
220             DISPLAY_LOGE("dump layer buffer failed");
221         }
222     }
223     return DISPLAY_SUCCESS;
224 }
225 
SetLayerCompositionType(CompositionType type)226 int32_t HdiLayer::SetLayerCompositionType(CompositionType type)
227 {
228     DISPLAY_LOGD("CompositionType type %{public}d", type);
229     mCompositionType = type;
230     return DISPLAY_SUCCESS;
231 }
232 
SetLayerBlendType(BlendType type)233 int32_t HdiLayer::SetLayerBlendType(BlendType type)
234 {
235     DISPLAY_LOGD("BlendType type %{public}d", type);
236     mBlendType = type;
237     return DISPLAY_SUCCESS;
238 }
239 
SetPixel(const BufferHandle & handle,int x,int y,uint32_t color)240 void HdiLayer::SetPixel(const BufferHandle &handle, int x, int y, uint32_t color)
241 {
242     const int32_t pixelBytes = 4;
243     DISPLAY_CHK_RETURN_NOT_VALUE((handle.format <= 0),
244         DISPLAY_LOGE("CheckPixel do not support format %{public}d", handle.format));
245     DISPLAY_CHK_RETURN_NOT_VALUE((handle.virAddr == nullptr), DISPLAY_LOGE("CheckPixel viraddr is null must map it"));
246     DISPLAY_CHK_RETURN_NOT_VALUE((x < 0 || x >= handle.width),
247         DISPLAY_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
248     DISPLAY_CHK_RETURN_NOT_VALUE((y < 0 || y >= handle.height),
249         DISPLAY_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
250     int32_t position = y * handle.width + x;
251     if ((position * pixelBytes) > handle.size) {
252         DISPLAY_LOGE("the pixel postion outside\n");
253     }
254     uint32_t *pixel = reinterpret_cast<uint32_t *>(handle.virAddr) + position;
255     *pixel = color;
256 }
257 
ClearColor(uint32_t color)258 void HdiLayer::ClearColor(uint32_t color)
259 {
260     DISPLAY_LOGD();
261     BufferHandle &handle = mHdiBuffer->mHandle;
262     for (int32_t x = 0; x < handle.width; x++) {
263         for (int32_t y = 0; y < handle.height; y++) {
264             SetPixel(handle, x, y, color);
265         }
266     }
267 }
268 
WaitAcquireFence()269 void HdiLayer::WaitAcquireFence()
270 {
271     int fd = GetAcquireFenceFd();
272     if (fd < 0) {
273         DISPLAY_LOGE("fd is invalid");
274         return;
275     }
276     sync_wait(fd, mFenceTimeOut);
277 }
278 } // namespace OHOS
279 } // namespace HDI
280 } // namespace DISPLAY
281