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 }