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 "layer_context.h" 17 18#include <securec.h> 19#include "hdi_log.h" 20 21using namespace OHOS; 22using namespace OHOS::Rosen; 23 24namespace { 25#define LOGI(fmt, ...) ::OHOS::HiviewDFX::HiLog::Info( \ 26 ::OHOS::HiviewDFX::HiLogLabel {LOG_CORE, 0, "HelloComposer"}, \ 27 "%{public}s: " fmt, __func__, ##__VA_ARGS__) 28#define LOGE(fmt, ...) ::OHOS::HiviewDFX::HiLog::Error( \ 29 ::OHOS::HiviewDFX::HiLogLabel {LOG_CORE, 0, "HelloComposer"}, \ 30 "%{public}s: " fmt, __func__, ##__VA_ARGS__) 31} 32 33LayerContext::LayerContext(GraphicIRect dst, GraphicIRect src, uint32_t zorder, LayerType layerType) 34 : dst_(dst), src_(src), zorder_(zorder), cSurface_(IConsumerSurface::Create()), layerType_(layerType) 35{ 36 cSurface_->SetDefaultWidthAndHeight(src.w, src.h); 37 cSurface_->SetDefaultUsage(BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA); 38 39 OHOS::sptr<IBufferProducer> producer = cSurface_->GetProducer(); 40 pSurface_ = Surface::CreateSurfaceAsProducer(producer); 41 cSurface_->RegisterConsumerListener(this); 42 43 hdiLayer_ = HdiLayerInfo::CreateHdiLayerInfo(); 44 LOGI("%{public}s: create surface w:%{public}d, h:%{public}d", __func__, src.w, src.h); 45} 46 47LayerContext::~LayerContext() 48{ 49 cSurface_ = nullptr; 50 pSurface_ = nullptr; 51 prevBuffer_ = nullptr; 52 hdiLayer_ = nullptr; 53} 54 55void LayerContext::OnBufferAvailable() 56{ 57} 58 59void LayerContext::SetTestClientStatus(bool status) 60{ 61 testClient_ = status; 62} 63 64void LayerContext::SetTestRotateStatus(bool status) 65{ 66 testRotate_ = status; 67} 68 69void LayerContext::SetTestYUVStatus(bool status) 70{ 71 testYUV_ = status; 72} 73 74void LayerContext::SetTestLayerColor(bool status) 75{ 76 testLayerColor_ = status; 77} 78 79OHOS::Rosen::LayerType LayerContext::GetLayerType() const 80{ 81 return layerType_; 82} 83 84const std::shared_ptr<HdiLayerInfo> LayerContext::GetHdiLayer() 85{ 86 return hdiLayer_; 87} 88 89SurfaceError LayerContext::DrawBufferColor() 90{ 91 OHOS::sptr<SurfaceBuffer> buffer; 92 int32_t releaseFence = -1; 93 BufferRequestConfig config = { 94 .width = src_.w, 95 .height = src_.h, 96 .strideAlignment = 0x8, 97 .format = GRAPHIC_PIXEL_FMT_RGBA_8888, 98 .usage = pSurface_->GetDefaultUsage(), 99 }; 100 101 if (layerType_ >= LayerType::LAYER_EXTRA && testYUV_) { 102 config.format = GRAPHIC_PIXEL_FMT_YCBCR_420_SP; 103 } 104 105 SurfaceError ret = pSurface_->RequestBuffer(buffer, releaseFence, config); 106 if (ret != 0) { 107 LOGE("RequestBuffer failed: %{public}s", SurfaceErrorStr(ret).c_str()); 108 return ret; 109 } 110 111 sptr<SyncFence> tempFence = new SyncFence(releaseFence); 112 tempFence->Wait(100); // 100 ms 113 114 if (buffer == nullptr) { 115 LOGE("%s: buffer is nullptr", __func__); 116 return SURFACE_ERROR_NULLPTR; 117 } 118 119 auto addr = static_cast<uint8_t *>(buffer->GetVirAddr()); 120 LOGI("buffer w:%{public}d h:%{public}d stride:%{public}d", buffer->GetWidth(), 121 buffer->GetHeight(), buffer->GetBufferHandle()->stride); 122 DrawColor(addr, buffer->GetWidth(), buffer->GetHeight()); 123 124 BufferFlushConfig flushConfig = { 125 .damage = { 126 .w = src_.w, 127 .h = src_.h, 128 }, 129 }; 130 131 ret = pSurface_->FlushBuffer(buffer, -1, flushConfig); 132 if (ret != SURFACE_ERROR_OK) { 133 LOGE("FlushBuffer failed"); 134 } 135 136 return ret; 137} 138 139void LayerContext::FillHDILayer() 140{ 141 GraphicLayerAlpha alpha = { .enPixelAlpha = true }; 142 hdiLayer_->SetZorder(static_cast<int32_t>(zorder_)); 143 hdiLayer_->SetAlpha(alpha); 144 if (layerType_ >= LayerType::LAYER_EXTRA) { 145 SetLayerTransformType(); 146 } 147 148 SetLayerCompositionType(); 149 std::vector<GraphicIRect> visibleRegions; 150 visibleRegions.emplace_back(src_); 151 hdiLayer_->SetVisibleRegions(visibleRegions); 152 std::vector<GraphicIRect> dirtyRegions; 153 dirtyRegions.emplace_back(src_); 154 hdiLayer_->SetDirtyRegions(dirtyRegions); 155 hdiLayer_->SetLayerSize(dst_); 156 157 if (testLayerColor_) { 158 hdiLayer_->SetBlendType(GraphicBlendType::GRAPHIC_BLEND_SRC); 159 } else { 160 hdiLayer_->SetBlendType(GraphicBlendType::GRAPHIC_BLEND_SRCOVER); 161 } 162 163 hdiLayer_->SetPreMulti(true); 164 hdiLayer_->SetCropRect(src_); 165} 166 167SurfaceError LayerContext::FillHDIBuffer() 168{ 169 OHOS::sptr<SurfaceBuffer> buffer = nullptr; 170 int32_t acquireFence = -1; 171 int64_t timestamp; 172 Rect damage; 173 SurfaceError ret = cSurface_->AcquireBuffer(buffer, acquireFence, timestamp, damage); 174 sptr<SyncFence> acquireSyncFence = new SyncFence(acquireFence); 175 if (ret != SURFACE_ERROR_OK) { 176 LOGE("Acquire buffer failed"); 177 return ret; 178 } 179 180 hdiLayer_->SetSurface(cSurface_); 181 182 if (testLayerColor_) { 183 if (layerType_ != LayerType::LAYER_LAUNCHER) { 184 hdiLayer_->SetBuffer(buffer, acquireSyncFence); 185 } else { 186 const uint32_t COLOR_R = 255; // 255 is red color 187 const uint32_t COLOR_G = 255; // 255 is green color 188 const uint32_t COLOR_B = 255; // 255 is blue color 189 const uint32_t COLOR_A = 255; // 255 is alpha 190 GraphicLayerColor color = { 191 .r = COLOR_R, 192 .g = COLOR_G, 193 .b = COLOR_B, 194 .a = COLOR_A 195 }; 196 197 hdiLayer_->SetLayerColor(color); 198 } 199 } else { 200 hdiLayer_->SetBuffer(buffer, acquireSyncFence); 201 } 202 203 prevBuffer_ = buffer; 204 prevFence_ = acquireSyncFence; 205 206 return ret; 207} 208 209void LayerContext::SetLayerTransformType() 210{ 211 if (!testRotate_) { 212 return; 213 } 214 215 static int32_t count = 0; 216 if (count >= 2000) { // 2000 is max cycle num 217 count = 0; 218 } 219 220 if (count >= 100 && count <= 200) { // 100-200 ROTATE_90 221 hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_90); 222 } else if (count >= 500 && count <= 600) { // 500-600 ROTATE_180 223 hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_180); 224 } else if (count >= 900 && count <= 1000) { // 900-1000 ROTATE_270 225 hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_270); 226 } else if (count >= 1300 && count <= 1400) { // 1300-1400 ROTATE_NONE 227 hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_NONE); 228 } 229 230 count++; 231} 232 233void LayerContext::SetLayerCompositionType() 234{ 235 if (layerType_ >= LayerType::LAYER_EXTRA && testClient_) { 236 hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT); 237 } else if (layerType_ == LayerType::LAYER_LAUNCHER && testLayerColor_) { 238 hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_SOLID_COLOR); 239 } else { 240 hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE); 241 } 242} 243 244void LayerContext::DrawColor(void *image, int width, int height) 245{ 246 if (layerType_ >= LayerType::LAYER_EXTRA) { 247 DrawExtraColor(image, static_cast<uint32_t>(width), static_cast<uint32_t>(height)); 248 } else { 249 DrawBaseColor(image, static_cast<uint32_t>(width), static_cast<uint32_t>(height)); 250 } 251} 252 253void LayerContext::DrawExtraColor(void *image, uint32_t width, uint32_t height) 254{ 255 frameCounter_ = frameCounter_ % 60; // 60 is cycle size 256 if (frameCounter_ == 0) { 257 colorIndex_ = colorIndex_ % colors_.size(); 258 color_ = colors_[colorIndex_]; 259 colorIndex_++; 260 } 261 frameCounter_++; 262 263 YUVPixel pixelValueYUV; 264 if (testYUV_) { 265 LOGI("DrawExtraColor with PIXEL_FMT_YCBCR_420_SP format."); 266 ConvertRBGA2YUV(color_, &pixelValueYUV); 267 DrawYUVColor(image, width, height, pixelValueYUV); 268 return; 269 } 270 271 LOGI("DrawExtraColor with GRAPHIC_PIXEL_FMT_RGBA_8888 format."); 272 uint32_t *pixel = static_cast<uint32_t *>(image); 273 for (uint32_t x = 0; x < width; x++) { 274 for (uint32_t y = 0; y < height; y++) { 275 if (testRotate_ && x <= 50) { // 0-50 is different color 276 *pixel++ = 0xffff1111; 277 } else { 278 *pixel++ = color_; 279 } 280 } 281 } 282} 283 284void LayerContext::DrawBaseColor(void *image, uint32_t width, uint32_t height) 285{ 286 static uint32_t value = 0x00; 287 if (layerType_ == LayerType::LAYER_STATUS) { 288 value = 0xfff0000f; 289 } else if (layerType_ == LayerType::LAYER_LAUNCHER) { 290 value = 0xffffffff; 291 } else { 292 value = 0xff00ffff; 293 } 294 295 uint32_t *pixel = static_cast<uint32_t *>(image); 296 for (uint32_t x = 0; x < width; x++) { 297 for (uint32_t y = 0; y < height; y++) { 298 *pixel++ = value; 299 } 300 } 301} 302 303void LayerContext::ConvertRBGA2YUV(uint32_t pixelValueRBGA, YUVPixel *pixelValueYUV) 304{ 305 // Get the components of pixelValueRBGA 306 uint8_t R = pixelValueRBGA >> RBGA_R_MOVEBITS; 307 uint8_t B = pixelValueRBGA >> RBGA_B_MOVEBITS; 308 uint8_t G = pixelValueRBGA >> RBGA_G_MOVEBITS; 309 310 // Convert pixel from RBGA formate to YUV formate with the formula: 311 // fixed formula : Y = 0.299 * R + 0.587 * G + 0.114 * B; 312 pixelValueYUV->y = 0.299 * R + 0.587 * G + 0.114 * B; 313 // fixed formula : U = -0.169 * R - 0.331 * G + 0.500 * B + 128; 314 pixelValueYUV->u = -0.169 * R - 0.331 * G + 0.500 * B + 128; 315 // fixed formula : V = 0.500 * R - 0.419 * G - 0.081 * B + 128; 316 pixelValueYUV->v = 0.500 * R - 0.419 * G - 0.081 * B + 128; 317} 318 319void LayerContext::DrawYUVColor(void *image, uint32_t width, uint32_t height, YUVPixel pixelValueYUV) 320{ 321 uint8_t *pixel = static_cast<uint8_t *>(image); 322 width = (width / PIXEL_LINE_ALIGNMENT + 1) * PIXEL_LINE_ALIGNMENT; 323 for (uint32_t index = 0; index < width * height * PIXEL_YCBCR420_BYTE; index++) { 324 if (index < width * height) { 325 *pixel++ = pixelValueYUV.y; 326 continue; 327 } 328 if (index % PIXEL_YCBCR420_UV_NUM == 0) { 329 *pixel++ = pixelValueYUV.u; 330 } else { 331 *pixel++ = pixelValueYUV.v; 332 } 333 } 334} 335 336