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