1 /*
2 * Copyright (c) 2023 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 "rs_rcd_surface_render_node.h"
17 #include <fstream>
18 #include "common/rs_singleton.h"
19 #include "platform/common/rs_log.h"
20 #include "transaction/rs_render_service_client.h"
21 #include "pipeline/rs_canvas_render_node.h"
22 #include "rs_round_corner_display_manager.h"
23
24 namespace OHOS {
25 namespace Rosen {
26
27 const unsigned long long PRIV_USAGE_FBC_CLD_LAYER = 1ULL << 56; // 56 means the buffer usage is hardware
28 const float RCD_LAYER_Z_TOP1 = static_cast<float>(0x7FFFFFFF); // toppest
29 const float RCD_LAYER_Z_TOP2 = static_cast<float>(0x7FFFFEFF); // not set toppest - 1, float only 6 significant digits
30 const int32_t BUFFER_TIME_OUT = 500;
31
RSRcdSurfaceRenderNode(NodeId id,RCDSurfaceType type,const std::weak_ptr<RSContext> & context)32 RSRcdSurfaceRenderNode::RSRcdSurfaceRenderNode(
33 NodeId id, RCDSurfaceType type, const std::weak_ptr<RSContext>& context)
34 : RSRenderNode(id, context), RSSurfaceHandler(id)
35 {
36 RS_LOGD("RCD: Start Create RSRcdSurfaceRenderNode %{public}d", type);
37 rcdExtInfo_.surfaceType = type;
38 MemoryInfo info = {sizeof(*this), ExtractPid(id), id, MEMORY_TYPE::MEM_RENDER_NODE};
39 MemoryTrack::Instance().AddNodeRecord(id, info);
40 }
41
Create(NodeId id,RCDSurfaceType type)42 RSRcdSurfaceRenderNode::SharedPtr RSRcdSurfaceRenderNode::Create(NodeId id, RCDSurfaceType type)
43 {
44 return std::make_shared<RSRcdSurfaceRenderNode>(id, type);
45 }
46
~RSRcdSurfaceRenderNode()47 RSRcdSurfaceRenderNode::~RSRcdSurfaceRenderNode()
48 {
49 MemoryTrack::Instance().RemoveNodeRecord(GetId());
50 }
51
GetSrcRect() const52 const RectI& RSRcdSurfaceRenderNode::GetSrcRect() const
53 {
54 return rcdExtInfo_.srcRect_;
55 }
56
GetDstRect() const57 const RectI& RSRcdSurfaceRenderNode::GetDstRect() const
58 {
59 return rcdExtInfo_.dstRect_;
60 }
61
SetRenderTargetId(NodeId id)62 void RSRcdSurfaceRenderNode::SetRenderTargetId(NodeId id)
63 {
64 renerTargetId_ = id;
65 }
66
CreateSurface(sptr<IBufferConsumerListener> listener)67 bool RSRcdSurfaceRenderNode::CreateSurface(sptr<IBufferConsumerListener> listener)
68 {
69 RS_LOGD("RCD: Start RSRcdSurfaceRenderNode CreateSurface");
70 if (consumer_ != nullptr && surface_ != nullptr) {
71 RS_LOGD("RSRcdSurfaceRenderNode::CreateSurface already created, return");
72 return true;
73 }
74 std::string surfaceName = "";
75 RoundCornerDisplayManager::RCDLayerType type = RoundCornerDisplayManager::RCDLayerType::INVALID;
76 if (IsTopSurface()) {
77 surfaceName = "RCDTopSurfaceNode" + std::to_string(renerTargetId_);
78 type = RoundCornerDisplayManager::RCDLayerType::TOP;
79 } else {
80 surfaceName = "RCDBottomSurfaceNode" + std::to_string(renerTargetId_);
81 type = RoundCornerDisplayManager::RCDLayerType::BOTTOM;
82 }
83 consumer_ = IConsumerSurface::Create(surfaceName.c_str());
84 RSSingleton<RoundCornerDisplayManager>::GetInstance().AddLayer(surfaceName, renerTargetId_, type);
85 if (consumer_ == nullptr) {
86 RS_LOGE("RSRcdSurfaceRenderNode::CreateSurface get consumer surface fail");
87 return false;
88 }
89 SurfaceError ret = consumer_->RegisterConsumerListener(listener);
90 if (ret != SURFACE_ERROR_OK) {
91 RS_LOGE("RSRcdSurfaceRenderNode::CreateSurface RegisterConsumerListener fail");
92 return false;
93 }
94 consumerListener_ = listener;
95 auto producer = consumer_->GetProducer();
96 sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
97 auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
98 surface_ = client->CreateRSSurface(surface);
99 rcdExtInfo_.surfaceCreated = true;
100 return true;
101 }
102
SetRcdBufferWidth(uint32_t width)103 void RSRcdSurfaceRenderNode::SetRcdBufferWidth(uint32_t width)
104 {
105 rcdSourceInfo.bufferWidth = width;
106 }
107
GetRcdBufferWidth() const108 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferWidth() const
109 {
110 return rcdSourceInfo.bufferWidth;
111 }
112
SetRcdBufferHeight(uint32_t height)113 void RSRcdSurfaceRenderNode::SetRcdBufferHeight(uint32_t height)
114 {
115 rcdSourceInfo.bufferHeight = height;
116 }
117
GetRcdBufferHeight() const118 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferHeight() const
119 {
120 return rcdSourceInfo.bufferHeight;
121 }
122
SetRcdBufferSize(uint32_t bufferSize)123 void RSRcdSurfaceRenderNode::SetRcdBufferSize(uint32_t bufferSize)
124 {
125 rcdSourceInfo.bufferSize = bufferSize;
126 }
127
GetRcdBufferSize() const128 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferSize() const
129 {
130 return rcdSourceInfo.bufferSize;
131 }
132
GetHardenBufferRequestConfig() const133 BufferRequestConfig RSRcdSurfaceRenderNode::GetHardenBufferRequestConfig() const
134 {
135 RS_LOGD("RCD: Start GetHardenBufferRequestConfig");
136 BufferRequestConfig config {};
137 config.width = static_cast<int32_t>(GetRcdBufferWidth());
138 if (GetRcdBufferWidth() != 0) {
139 // need to plus 2 while calculating the bufferHeight in hardware dss way
140 config.height = static_cast<int32_t>(GetRcdBufferSize() / GetRcdBufferWidth() + GetRcdBufferHeight() + 2);
141 }
142 config.strideAlignment = 0x8; // default stride is 8 Bytes. // output parameter, system components can ignore it
143 config.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
144 config.usage = BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_HW_COMPOSER | BUFFER_USAGE_MEM_DMA
145 | PRIV_USAGE_FBC_CLD_LAYER;
146 RS_LOGD("RCD: GetHardenBufferRequestConfig Buffer usage %{public}" PRIu64 ", width %{public}d, height %{public}d",
147 config.usage, config.width, config.height);
148 config.timeout = BUFFER_TIME_OUT; // ms
149 return config;
150 }
151
PrepareHardwareResourceBuffer(const std::shared_ptr<rs_rcd::RoundCornerLayer> & layerInfo)152 bool RSRcdSurfaceRenderNode::PrepareHardwareResourceBuffer(const std::shared_ptr<rs_rcd::RoundCornerLayer>& layerInfo)
153 {
154 RS_LOGD("RCD: Start PrepareHardwareResourceBuffer");
155
156 if (layerInfo == nullptr) {
157 RS_LOGE("RCD: layerInfo is nullptr");
158 return false;
159 }
160
161 cldLayerInfo.pathBin = std::string(rs_rcd::PATH_CONFIG_DIR) + "/" + layerInfo->binFileName;
162 cldLayerInfo.bufferSize = layerInfo->bufferSize;
163 cldLayerInfo.cldWidth = layerInfo->cldWidth;
164 cldLayerInfo.cldHeight = layerInfo->cldHeight;
165
166 if (layerInfo->curBitmap == nullptr) {
167 RS_LOGE("layerInfo->curBitmap is nullptr");
168 return false;
169 }
170 layerBitmap = *(layerInfo->curBitmap);
171 uint32_t bitmapHeight = static_cast<uint32_t>(layerBitmap.GetHeight());
172 uint32_t bitmapWidth = static_cast<uint32_t>(layerBitmap.GetWidth());
173 if (bitmapHeight <= 0 || bitmapWidth <= 0 || layerInfo->layerHeight <= 0) {
174 RS_LOGE("bitmapHeight, bitmapWidth or layerHeight is wrong value");
175 return false;
176 }
177 SetRcdBufferHeight(bitmapHeight);
178 SetRcdBufferWidth(bitmapWidth);
179 SetRcdBufferSize(cldLayerInfo.bufferSize);
180
181 if (IsTopSurface()) {
182 rcdExtInfo_.srcRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
183 rcdExtInfo_.dstRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
184 SetGlobalZOrder(RCD_LAYER_Z_TOP1);
185 } else {
186 rcdExtInfo_.srcRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
187 rcdExtInfo_.dstRect_ = RectI(0, layerInfo->layerHeight - bitmapHeight, bitmapWidth, bitmapHeight);
188 SetGlobalZOrder(RCD_LAYER_Z_TOP2);
189 }
190 return true;
191 }
192
SetHardwareResourceToBuffer()193 bool RSRcdSurfaceRenderNode::SetHardwareResourceToBuffer()
194 {
195 RS_LOGD("RCD: Start RSRcdSurfaceRenderNode::SetHardwareResourceToBuffer");
196 if (layerBitmap.IsValid()) {
197 RS_LOGE("LayerBitmap is not valid");
198 return false;
199 }
200 sptr<SurfaceBuffer> nodeBuffer = GetBuffer();
201 if (nodeBuffer == nullptr) {
202 RS_LOGE("RSRcdSurfaceRenderNode buffer is nullptr");
203 return false;
204 }
205 Drawing::ImageInfo imgInfo = Drawing::ImageInfo::MakeN32Premul(nodeBuffer->GetWidth(), nodeBuffer->GetHeight());
206 if (!layerBitmap.ReadPixels(imgInfo, reinterpret_cast<void*>(nodeBuffer->GetVirAddr()),
207 nodeBuffer->GetStride(), 0, 0)) {
208 RS_LOGE("RSRcdSurfaceRenderNode:: copy layerBitmap to buffer failed");
209 return false;
210 }
211 if (!FillHardwareResource(cldLayerInfo, layerBitmap.GetHeight(), layerBitmap.GetWidth())) {
212 RS_LOGE("RSRcdSurfaceRenderNode:: copy hardware resource to buffer failed");
213 return false;
214 }
215 return true;
216 }
217
FillHardwareResource(HardwareLayerInfo & cldLayerInfo,int height,int width)218 bool RSRcdSurfaceRenderNode::FillHardwareResource(HardwareLayerInfo &cldLayerInfo,
219 int height, int width)
220 {
221 sptr<SurfaceBuffer> nodeBuffer = GetBuffer();
222 if (nodeBuffer == nullptr) {
223 RS_LOGE("RSRcdSurfaceRenderNode buffer is nullptr");
224 return false;
225 }
226 if (cldLayerInfo.bufferSize < 0 || cldLayerInfo.cldWidth < 0 ||
227 cldLayerInfo.cldHeight < 0 || width < 0 || height < 0) {
228 RS_LOGE("RSRcdSurfaceRenderNode check cldLayerInfo and size failed");
229 return false;
230 }
231 const uint32_t bytesPerPixel = 4; // 4 means four bytes per pixel
232 cldInfo_.cldSize = static_cast<uint32_t>(cldLayerInfo.bufferSize);
233 cldInfo_.cldWidth = static_cast<uint32_t>(cldLayerInfo.cldWidth);
234 cldInfo_.cldHeight = static_cast<uint32_t>(cldLayerInfo.cldHeight);
235 cldInfo_.cldStride = static_cast<uint32_t>(cldLayerInfo.cldWidth * bytesPerPixel);
236 cldInfo_.exWidth = static_cast<uint32_t>(width);
237 cldInfo_.exHeight = static_cast<uint32_t>(height);
238
239 int offset = 0;
240 int offsetCldInfo = 0;
241 int stride = nodeBuffer->GetStride();
242 offsetCldInfo = height * stride;
243 offset = (height + 1) * stride;
244 cldInfo_.cldDataOffset = static_cast<uint32_t>(offset);
245 uint8_t *img = static_cast<uint8_t*>(nodeBuffer->GetVirAddr());
246 uint32_t bufferSize = nodeBuffer->GetSize();
247 if (img == nullptr || offsetCldInfo < 0 || bufferSize < static_cast<uint32_t>(offsetCldInfo) + sizeof(cldInfo_)) {
248 RS_LOGE("[%s] check nodebuffer failed", __func__);
249 return false;
250 }
251 errno_t ret = memcpy_s(reinterpret_cast<void*>(img + offsetCldInfo), sizeof(cldInfo_), &cldInfo_, sizeof(cldInfo_));
252 if (ret != EOK) {
253 RS_LOGE("[%s] memcpy_s failed", __func__);
254 return false;
255 }
256 std::ifstream addBufferFile(cldLayerInfo.pathBin, std::ifstream::binary | std::ifstream::in);
257 if (addBufferFile) {
258 addBufferFile.seekg(0, addBufferFile.end);
259 int addBufferSize = addBufferFile.tellg();
260 addBufferFile.seekg(0, addBufferFile.beg);
261 addBufferFile.read(reinterpret_cast<char*>(img + offset), addBufferSize);
262 addBufferFile.close();
263 } else {
264 RS_LOGE("[%{public}s] hardware fopen error", __func__);
265 return false;
266 }
267 return true;
268 }
269
IsSurfaceCreated() const270 bool RSRcdSurfaceRenderNode::IsSurfaceCreated() const
271 {
272 return rcdExtInfo_.surfaceCreated;
273 }
274
275 #ifdef NEW_RENDER_CONTEXT
GetRSSurface() const276 std::shared_ptr<RSRenderSurface> RSRcdSurfaceRenderNode::GetRSSurface() const
277 #else
278 std::shared_ptr<RSSurface> RSRcdSurfaceRenderNode::GetRSSurface() const
279 #endif
280 {
281 return surface_;
282 }
283
GetConsumerListener() const284 sptr<IBufferConsumerListener> RSRcdSurfaceRenderNode::GetConsumerListener() const
285 {
286 return consumerListener_;
287 }
288
ClearBufferCache()289 void RSRcdSurfaceRenderNode::ClearBufferCache()
290 {
291 if (surface_ != nullptr) {
292 surface_->ClearBuffer();
293 }
294 if (consumer_ != nullptr) {
295 consumer_->GoBackground();
296 }
297 }
298
ResetCurrFrameState()299 void RSRcdSurfaceRenderNode::ResetCurrFrameState()
300 {
301 rcdExtInfo_.srcRect_.Clear();
302 rcdExtInfo_.dstRect_.Clear();
303 rcdExtInfo_.surfaceBounds.Clear();
304 rcdExtInfo_.frameBounds.Clear();
305 rcdExtInfo_.frameViewPort.Clear();
306 }
307
Reset()308 void RSRcdSurfaceRenderNode::Reset()
309 {
310 ResetCurrFrameState();
311 }
312
IsBottomSurface() const313 bool RSRcdSurfaceRenderNode::IsBottomSurface() const
314 {
315 return rcdExtInfo_.surfaceType == RCDSurfaceType::BOTTOM;
316 }
317
IsTopSurface() const318 bool RSRcdSurfaceRenderNode::IsTopSurface() const
319 {
320 return rcdExtInfo_.surfaceType == RCDSurfaceType::TOP;
321 }
322
IsInvalidSurface() const323 bool RSRcdSurfaceRenderNode::IsInvalidSurface() const
324 {
325 return rcdExtInfo_.surfaceType == RCDSurfaceType::INVALID;
326 }
327
GetSurfaceWidth() const328 float RSRcdSurfaceRenderNode::GetSurfaceWidth() const
329 {
330 return rcdExtInfo_.surfaceBounds.GetWidth();
331 }
332
GetSurfaceHeight() const333 float RSRcdSurfaceRenderNode::GetSurfaceHeight() const
334 {
335 return rcdExtInfo_.surfaceBounds.GetHeight();
336 }
337
GetFrameOffsetX() const338 float RSRcdSurfaceRenderNode::GetFrameOffsetX() const
339 {
340 return rcdExtInfo_.GetFrameOffsetX();
341 }
342
GetFrameOffsetY() const343 float RSRcdSurfaceRenderNode::GetFrameOffsetY() const
344 {
345 return rcdExtInfo_.GetFrameOffsetY();
346 }
347
GetCldInfo() const348 const CldInfo& RSRcdSurfaceRenderNode::GetCldInfo() const
349 {
350 return cldInfo_;
351 }
352 } // namespace Rosen
353 } // namespace OHOS