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