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(IRect dst,IRect src,uint32_t zorder,LayerType layerType)26 LayerContext::LayerContext(IRect dst, IRect src, uint32_t zorder, LayerType layerType)
27 : dst_(dst), src_(src), zorder_(zorder), layerType_(layerType)
28 {
29 cSurface_ = Surface::CreateSurfaceAsConsumer();
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 hdiLayer_->SetVisibleRegion(1, src_);
124 hdiLayer_->SetDirtyRegion(src_);
125 hdiLayer_->SetLayerSize(dst_);
126 hdiLayer_->SetBlendType(GraphicBlendType::GRAPHIC_BLEND_SRCOVER);
127 hdiLayer_->SetCropRect(src_);
128 hdiLayer_->SetPreMulti(false);
129
130 prevBuffer_ = buffer;
131 prevFence_ = acquireSyncFence;
132
133 return ret;
134 }
135
DrawBaseLayer(void * image,int width,int height,TestFunc testFunc)136 void LayerContext::DrawBaseLayer(void* image, int width, int height, TestFunc testFunc)
137 {
138 Bitmap bitmap;
139 BitmapFormat format { COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE };
140 bitmap.Build(width, height, format);
141
142 Canvas canvas;
143 canvas.Bind(bitmap);
144 if (layerType_ == LayerType::LAYER_LAUNCHER) {
145 canvas.Clear(Color::COLOR_WHITE);
146 testFunc(canvas, width, height);
147 }
148 constexpr uint32_t stride = 4;
149 int32_t addrSize = width * height * stride;
150 auto ret = memcpy_s(image, addrSize, bitmap.GetPixels(), addrSize);
151 if (ret != EOK) {
152 LOGE("memcpy_s failed");
153 }
154 }