1 /*
2  * Copyright (c) 2022 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 
20 #include "hdi_log.h"
21 
22 using namespace OHOS;
23 using namespace Rosen;
24 using namespace Drawing;
25 
LayerContext(GraphicIRect dst,GraphicIRect src,uint32_t zorder,LayerType layerType)26 LayerContext::LayerContext(GraphicIRect dst, GraphicIRect src, uint32_t zorder, LayerType layerType)
27     : dst_(dst), src_(src), zorder_(zorder), layerType_(layerType)
28 {
29     cSurface_ = IConsumerSurface::Create();
30     cSurface_->SetDefaultWidthAndHeight(src.w, src.h);
31     cSurface_->SetDefaultUsage(BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA);
32 
33     OHOS::sptr<IBufferProducer> producer = cSurface_->GetProducer();
34     pSurface_ = Surface::CreateSurfaceAsProducer(producer);
35     cSurface_->RegisterConsumerListener(this);
36 
37     hdiLayer_ = HdiLayerInfo::CreateHdiLayerInfo();
38     LOGI("%{public}s: create surface w:%{public}d, h:%{public}d", __func__, src.w, src.h);
39 }
40 
~LayerContext()41 LayerContext::~LayerContext()
42 {
43     cSurface_ = nullptr;
44     pSurface_ = nullptr;
45     prevBuffer_ = nullptr;
46     hdiLayer_ = nullptr;
47 }
48 
OnBufferAvailable()49 void LayerContext::OnBufferAvailable() {}
50 
GetHdiLayer()51 const std::shared_ptr<HdiLayerInfo> LayerContext::GetHdiLayer()
52 {
53     return hdiLayer_;
54 }
55 
DrawBuffer(TestFunc testFunc)56 SurfaceError LayerContext::DrawBuffer(TestFunc testFunc)
57 {
58     OHOS::sptr<SurfaceBuffer> buffer;
59     int32_t releaseFence = -1;
60     BufferRequestConfig config = {
61         .width = src_.w,
62         .height = src_.h,
63         .strideAlignment = 0x8,
64         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
65         .usage = pSurface_->GetDefaultUsage(),
66     };
67 
68     SurfaceError ret = pSurface_->RequestBuffer(buffer, releaseFence, config);
69     if (ret != 0) {
70         LOGE("RequestBuffer failed: %{public}s", SurfaceErrorStr(ret).c_str());
71         return ret;
72     }
73 
74     sptr<SyncFence> tempFence = new SyncFence(releaseFence);
75     tempFence->Wait(100); // 100 ms
76 
77     if (buffer == nullptr) {
78         LOGE("%s: buffer is nullptr", __func__);
79         return SURFACE_ERROR_NULLPTR;
80     }
81 
82     auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
83     LOGI("buffer w:%{public}d h:%{public}d stride:%{public}d", buffer->GetWidth(), buffer->GetHeight(),
84         buffer->GetBufferHandle()->stride);
85     DrawBaseLayer(addr, buffer->GetWidth(), buffer->GetHeight(), testFunc);
86 
87     BufferFlushConfig flushConfig = {
88         .damage = {
89         .w = src_.w,
90         .h = src_.h,
91         },
92     };
93 
94     ret = pSurface_->FlushBuffer(buffer, -1, flushConfig);
95     if (ret != SURFACE_ERROR_OK) {
96         LOGE("FlushBuffer failed");
97     }
98 
99     return ret;
100 }
101 
FillHDILayer()102 SurfaceError LayerContext::FillHDILayer()
103 {
104     OHOS::sptr<SurfaceBuffer> buffer = nullptr;
105     int32_t acquireFence = -1;
106     int64_t timestamp;
107     OHOS::Rect damage;
108     SurfaceError ret = cSurface_->AcquireBuffer(buffer, acquireFence, timestamp, damage);
109     UniqueFd acquireFenceFd(acquireFence);
110     if (ret != SURFACE_ERROR_OK) {
111         LOGE("Acquire buffer failed");
112         return ret;
113     }
114 
115     GraphicLayerAlpha alpha = { .enPixelAlpha = true };
116 
117     hdiLayer_->SetSurface(cSurface_);
118     auto acquireSyncFence = new SyncFence(acquireFenceFd.Release());
119     hdiLayer_->SetBuffer(buffer, acquireSyncFence);
120     hdiLayer_->SetZorder(static_cast<int32_t>(zorder_));
121     hdiLayer_->SetAlpha(alpha);
122     hdiLayer_->SetCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
123     std::vector<GraphicIRect> visibleRegions;
124     visibleRegions.emplace_back(src_);
125     hdiLayer_->SetVisibleRegions(visibleRegions);
126     std::vector<GraphicIRect> dirtyRegions;
127     dirtyRegions.emplace_back(src_);
128     hdiLayer_->SetDirtyRegions(dirtyRegions);
129     hdiLayer_->SetLayerSize(dst_);
130     hdiLayer_->SetBlendType(GraphicBlendType::GRAPHIC_BLEND_SRCOVER);
131     hdiLayer_->SetCropRect(src_);
132     hdiLayer_->SetPreMulti(false);
133 
134     prevBuffer_ = buffer;
135     prevFence_ = acquireSyncFence;
136 
137     return ret;
138 }
139 
DrawBaseLayer(void * image,int width,int height,TestFunc testFunc)140 void LayerContext::DrawBaseLayer(void* image, int width, int height, TestFunc testFunc)
141 {
142     Bitmap bitmap;
143     BitmapFormat format { COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE };
144     bitmap.Build(width, height, format);
145 
146     Canvas canvas;
147     canvas.Bind(bitmap);
148     if (layerType_ == LayerType::LAYER_LAUNCHER) {
149         canvas.Clear(Color::COLOR_WHITE);
150         testFunc(canvas, width, height);
151     }
152     constexpr uint32_t stride = 4;
153     int32_t addrSize = width * height * stride;
154     auto ret = memcpy_s(image, addrSize, bitmap.GetPixels(), addrSize);
155     if (ret != EOK) {
156         LOGE("memcpy_s failed");
157     }
158 }