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(GraphicIRect dst,GraphicIRect src,uint32_t zorder,LayerType layerType)33 LayerContext::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
~LayerContext()47 LayerContext::~LayerContext()
48 {
49 cSurface_ = nullptr;
50 pSurface_ = nullptr;
51 prevBuffer_ = nullptr;
52 hdiLayer_ = nullptr;
53 }
54
OnBufferAvailable()55 void LayerContext::OnBufferAvailable()
56 {
57 }
58
SetTestClientStatus(bool status)59 void LayerContext::SetTestClientStatus(bool status)
60 {
61 testClient_ = status;
62 }
63
SetTestRotateStatus(bool status)64 void LayerContext::SetTestRotateStatus(bool status)
65 {
66 testRotate_ = status;
67 }
68
SetTestYUVStatus(bool status)69 void LayerContext::SetTestYUVStatus(bool status)
70 {
71 testYUV_ = status;
72 }
73
SetTestLayerColor(bool status)74 void LayerContext::SetTestLayerColor(bool status)
75 {
76 testLayerColor_ = status;
77 }
78
GetLayerType() const79 OHOS::Rosen::LayerType LayerContext::GetLayerType() const
80 {
81 return layerType_;
82 }
83
GetHdiLayer()84 const std::shared_ptr<HdiLayerInfo> LayerContext::GetHdiLayer()
85 {
86 return hdiLayer_;
87 }
88
DrawBufferColor()89 SurfaceError 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
FillHDILayer()139 void 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
FillHDIBuffer()167 SurfaceError 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
SetLayerTransformType()209 void 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
SetLayerCompositionType()233 void 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
DrawColor(void * image,int width,int height)244 void 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
DrawExtraColor(void * image,uint32_t width,uint32_t height)253 void 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
DrawBaseColor(void * image,uint32_t width,uint32_t height)284 void 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
ConvertRBGA2YUV(uint32_t pixelValueRBGA,YUVPixel * pixelValueYUV)303 void 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
DrawYUVColor(void * image,uint32_t width,uint32_t height,YUVPixel pixelValueYUV)319 void 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