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