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