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