• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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), layerType_(layerType)
35 {
36     cSurface_ = IConsumerSurface::Create();
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     std::vector<GraphicIRect> visibleRegions;
160     visibleRegions.emplace_back(src_);
161     hdiLayer_->SetVisibleRegions(visibleRegions);
162     std::vector<GraphicIRect> dirtyRegions;
163     dirtyRegions.emplace_back(src_);
164     hdiLayer_->SetDirtyRegions(dirtyRegions);
165     hdiLayer_->SetLayerSize(dst_);
166     hdiLayer_->SetBlendType(GraphicBlendType::GRAPHIC_BLEND_SRCOVER);
167     hdiLayer_->SetCropRect(src_);
168     hdiLayer_->SetPreMulti(false);
169 
170     prevBuffer_ = buffer;
171     prevFence_ = acquireSyncFence;
172 
173     return ret;
174 }
175 
SetLayerTransformType()176 void LayerContext::SetLayerTransformType()
177 {
178     if (!testRotate_) {
179         return;
180     }
181 
182     static int32_t count = 0;
183     if (count >= 2000) { // 2000 is max cycle num
184         count = 0;
185     }
186 
187     if (count >= 100 && count <= 200) { // 100-200 ROTATE_90
188         hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_90);
189     } else if (count >= 500 && count <= 600) { // 500-600 ROTATE_180
190         hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_180);
191     } else if (count >= 900 && count <= 1000) { // 900-1000 ROTATE_270
192         hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_270);
193     } else if (count >= 1300 && count <= 1400) { // 1300-1400 ROTATE_NONE
194         hdiLayer_->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_NONE);
195     }
196 
197     count++;
198 }
199 
SetLayerCompositionType()200 void LayerContext::SetLayerCompositionType()
201 {
202     if (layerType_ >= LayerType::LAYER_EXTRA && testClient_) {
203         hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT);
204     } else {
205         hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
206     }
207 }
208 
DrawColor(void * image,int width,int height)209 void LayerContext::DrawColor(void *image, int width, int height)
210 {
211     if (layerType_ >= LayerType::LAYER_EXTRA) {
212         DrawExtraColor(image, static_cast<uint32_t>(width), static_cast<uint32_t>(height));
213     } else {
214         DrawBaseColor(image, static_cast<uint32_t>(width), static_cast<uint32_t>(height));
215     }
216 }
217 
DrawExtraColor(void * image,uint32_t width,uint32_t height)218 void LayerContext::DrawExtraColor(void *image, uint32_t width, uint32_t height)
219 {
220     frameCounter_ = frameCounter_ % 60; // 60 is cycle size
221     if (frameCounter_ == 0) {
222         colorIndex_ = colorIndex_ % colors_.size();
223         color_ = colors_[colorIndex_];
224         colorIndex_++;
225     }
226     frameCounter_++;
227 
228     YUVPixel pixelValueYUV;
229     if (testYUV_) {
230         LOGI("DrawExtraColor with PIXEL_FMT_YCBCR_420_SP format.");
231         ConvertRBGA2YUV(color_, &pixelValueYUV);
232         DrawYUVColor(image, width, height, pixelValueYUV);
233         return;
234     }
235 
236     LOGI("DrawExtraColor with GRAPHIC_PIXEL_FMT_RGBA_8888 format.");
237     uint32_t *pixel = static_cast<uint32_t *>(image);
238     for (uint32_t x = 0; x < width; x++) {
239         for (uint32_t y = 0;  y < height; y++) {
240             if (testRotate_ && x <= 50) { // 0-50 is different color
241                 *pixel++ = 0xffff1111;
242             } else {
243                 *pixel++ = color_;
244             }
245         }
246     }
247 }
248 
DrawBaseColor(void * image,uint32_t width,uint32_t height)249 void LayerContext::DrawBaseColor(void *image, uint32_t width, uint32_t height)
250 {
251     static uint32_t value = 0x00;
252     if (layerType_ == LayerType::LAYER_STATUS) {
253         value = 0xfff0000f;
254     } else if (layerType_ == LayerType::LAYER_LAUNCHER) {
255         value = 0xffffffff;
256     } else {
257         value = 0xff00ffff;
258     }
259 
260     uint32_t *pixel = static_cast<uint32_t *>(image);
261     for (uint32_t x = 0; x < width; x++) {
262         for (uint32_t y = 0;  y < height; y++) {
263             *pixel++ = value;
264         }
265     }
266 }
267 
ConvertRBGA2YUV(uint32_t pixelValueRBGA,YUVPixel * pixelValueYUV)268 void LayerContext::ConvertRBGA2YUV(uint32_t pixelValueRBGA, YUVPixel *pixelValueYUV)
269 {
270     // Get the components of pixelValueRBGA
271     uint8_t R = pixelValueRBGA >> RBGA_R_MOVEBITS;
272     uint8_t B = pixelValueRBGA >> RBGA_B_MOVEBITS;
273     uint8_t G = pixelValueRBGA >> RBGA_G_MOVEBITS;
274 
275     // Convert pixel from RBGA formate to YUV formate with the formula:
276     // fixed formula : Y = 0.299 * R + 0.587 * G + 0.114 * B;
277     pixelValueYUV->y = 0.299 * R + 0.587 * G + 0.114 * B;
278     // fixed formula : U = -0.169 * R - 0.331 * G + 0.500 * B + 128;
279     pixelValueYUV->u = -0.169 * R - 0.331 * G + 0.500 * B + 128;
280     // fixed formula : V = 0.500 * R - 0.419 * G - 0.081 * B + 128;
281     pixelValueYUV->v = 0.500 * R - 0.419 * G - 0.081 * B + 128;
282 }
283 
DrawYUVColor(void * image,uint32_t width,uint32_t height,YUVPixel pixelValueYUV)284 void LayerContext::DrawYUVColor(void *image, uint32_t width, uint32_t height, YUVPixel pixelValueYUV)
285 {
286     uint8_t *pixel = static_cast<uint8_t *>(image);
287     width = (width / PIXEL_LINE_ALIGNMENT + 1) * PIXEL_LINE_ALIGNMENT;
288     for (uint32_t index = 0; index < width * height * PIXEL_YCBCR420_BYTE; index++) {
289         if (index < width * height) {
290             *pixel++ = pixelValueYUV.y;
291             continue;
292         }
293         if (index % PIXEL_YCBCR420_UV_NUM == 0) {
294             *pixel++ = pixelValueYUV.u;
295         } else {
296             *pixel++ = pixelValueYUV.v;
297         }
298     }
299 }
300 
301