• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     MemorySnapshot::Instance().AddCpuMemory(ExtractPid(id), sizeof(*this));
41 }
42 
Create(NodeId id,RCDSurfaceType type)43 RSRcdSurfaceRenderNode::SharedPtr RSRcdSurfaceRenderNode::Create(NodeId id, RCDSurfaceType type)
44 {
45     return std::make_shared<RSRcdSurfaceRenderNode>(id, type);
46 }
47 
~RSRcdSurfaceRenderNode()48 RSRcdSurfaceRenderNode::~RSRcdSurfaceRenderNode()
49 {
50     MemoryTrack::Instance().RemoveNodeRecord(GetId());
51     MemorySnapshot::Instance().RemoveCpuMemory(ExtractPid(GetId()), sizeof(*this));
52 }
53 
GetSrcRect() const54 const RectI& RSRcdSurfaceRenderNode::GetSrcRect() const
55 {
56     return rcdExtInfo_.srcRect_;
57 }
58 
GetDstRect() const59 const RectI& RSRcdSurfaceRenderNode::GetDstRect() const
60 {
61     return rcdExtInfo_.dstRect_;
62 }
63 
SetRenderTargetId(NodeId id)64 void RSRcdSurfaceRenderNode::SetRenderTargetId(NodeId id)
65 {
66     renerTargetId_ = id;
67 }
68 
CreateSurface(sptr<IBufferConsumerListener> listener)69 bool RSRcdSurfaceRenderNode::CreateSurface(sptr<IBufferConsumerListener> listener)
70 {
71     RS_LOGD("RCD: Start RSRcdSurfaceRenderNode CreateSurface");
72     if (consumer_ != nullptr && surface_ != nullptr) {
73         RS_LOGD("RSRcdSurfaceRenderNode::CreateSurface already created, return");
74         return true;
75     }
76     std::string surfaceName = "";
77     RoundCornerDisplayManager::RCDLayerType type = RoundCornerDisplayManager::RCDLayerType::INVALID;
78     if (IsTopSurface()) {
79         surfaceName = "RCDTopSurfaceNode" + std::to_string(renerTargetId_);
80         type = RoundCornerDisplayManager::RCDLayerType::TOP;
81     } else {
82         surfaceName = "RCDBottomSurfaceNode" + std::to_string(renerTargetId_);
83         type = RoundCornerDisplayManager::RCDLayerType::BOTTOM;
84     }
85     consumer_ = IConsumerSurface::Create(surfaceName.c_str());
86     RSSingleton<RoundCornerDisplayManager>::GetInstance().AddLayer(surfaceName, renerTargetId_, type);
87     if (consumer_ == nullptr) {
88         RS_LOGE("RSRcdSurfaceRenderNode::CreateSurface get consumer surface fail");
89         return false;
90     }
91     SurfaceError ret = consumer_->RegisterConsumerListener(listener);
92     if (ret != SURFACE_ERROR_OK) {
93         RS_LOGE("RSRcdSurfaceRenderNode::CreateSurface RegisterConsumerListener fail");
94         return false;
95     }
96     consumerListener_ = listener;
97     auto producer = consumer_->GetProducer();
98     sptr<Surface> surface = Surface::CreateSurfaceAsProducer(producer);
99     auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
100     surface_ = client->CreateRSSurface(surface);
101     rcdExtInfo_.surfaceCreated = true;
102     return true;
103 }
104 
SetRcdBufferWidth(uint32_t width)105 void RSRcdSurfaceRenderNode::SetRcdBufferWidth(uint32_t width)
106 {
107     rcdSourceInfo.bufferWidth = width;
108 }
109 
GetRcdBufferWidth() const110 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferWidth() const
111 {
112     return rcdSourceInfo.bufferWidth;
113 }
114 
SetRcdBufferHeight(uint32_t height)115 void RSRcdSurfaceRenderNode::SetRcdBufferHeight(uint32_t height)
116 {
117     rcdSourceInfo.bufferHeight = height;
118 }
119 
GetRcdBufferHeight() const120 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferHeight() const
121 {
122     return rcdSourceInfo.bufferHeight;
123 }
124 
SetRcdBufferSize(uint32_t bufferSize)125 void RSRcdSurfaceRenderNode::SetRcdBufferSize(uint32_t bufferSize)
126 {
127     rcdSourceInfo.bufferSize = bufferSize;
128 }
129 
GetRcdBufferSize() const130 uint32_t RSRcdSurfaceRenderNode::GetRcdBufferSize() const
131 {
132     return rcdSourceInfo.bufferSize;
133 }
134 
GetHardenBufferRequestConfig() const135 BufferRequestConfig RSRcdSurfaceRenderNode::GetHardenBufferRequestConfig() const
136 {
137     RS_LOGD("RCD: Start GetHardenBufferRequestConfig");
138     BufferRequestConfig config {};
139     config.width = static_cast<int32_t>(GetRcdBufferWidth());
140     if (GetRcdBufferWidth() != 0) {
141         // need to plus 2 while calculating the bufferHeight in hardware dss way
142         config.height = static_cast<int32_t>(GetRcdBufferSize() / GetRcdBufferWidth() + GetRcdBufferHeight() + 2);
143     }
144     config.strideAlignment = 0x8; // default stride is 8 Bytes.  // output parameter, system components can ignore it
145     config.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
146     config.usage = BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_HW_COMPOSER | BUFFER_USAGE_MEM_DMA
147         | PRIV_USAGE_FBC_CLD_LAYER;
148     RS_LOGD("RCD: GetHardenBufferRequestConfig Buffer usage %{public}" PRIu64 ", width %{public}d, height %{public}d",
149         config.usage, config.width, config.height);
150     config.timeout = BUFFER_TIME_OUT; // ms
151     return config;
152 }
153 
PrepareHardwareResourceBuffer(const std::shared_ptr<rs_rcd::RoundCornerLayer> & layerInfo)154 bool RSRcdSurfaceRenderNode::PrepareHardwareResourceBuffer(const std::shared_ptr<rs_rcd::RoundCornerLayer>& layerInfo)
155 {
156     RS_LOGD("RCD: Start PrepareHardwareResourceBuffer");
157 
158     if (layerInfo == nullptr) {
159         RS_LOGE("RCD: layerInfo is nullptr");
160         return false;
161     }
162 
163     cldLayerInfo.pathBin = std::string(rs_rcd::PATH_CONFIG_DIR) + "/" + layerInfo->binFileName;
164     cldLayerInfo.bufferSize = layerInfo->bufferSize;
165     cldLayerInfo.cldWidth = layerInfo->cldWidth;
166     cldLayerInfo.cldHeight = layerInfo->cldHeight;
167 
168     if (layerInfo->curBitmap == nullptr) {
169         RS_LOGE("layerInfo->curBitmap is nullptr");
170         return false;
171     }
172     layerBitmap = *(layerInfo->curBitmap);
173     uint32_t bitmapHeight = static_cast<uint32_t>(layerBitmap.GetHeight());
174     uint32_t bitmapWidth = static_cast<uint32_t>(layerBitmap.GetWidth());
175     if (bitmapHeight <= 0 || bitmapWidth <= 0 || layerInfo->layerHeight <= 0) {
176         RS_LOGE("bitmapHeight, bitmapWidth or layerHeight is wrong value");
177         return false;
178     }
179     SetRcdBufferHeight(bitmapHeight);
180     SetRcdBufferWidth(bitmapWidth);
181     SetRcdBufferSize(cldLayerInfo.bufferSize);
182 
183     if (IsTopSurface()) {
184         rcdExtInfo_.srcRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
185         rcdExtInfo_.dstRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
186         SetGlobalZOrder(RCD_LAYER_Z_TOP1);
187     } else {
188         rcdExtInfo_.srcRect_ = RectI(0, 0, bitmapWidth, bitmapHeight);
189         rcdExtInfo_.dstRect_ = RectI(0, layerInfo->layerHeight - bitmapHeight, bitmapWidth, bitmapHeight);
190         SetGlobalZOrder(RCD_LAYER_Z_TOP2);
191     }
192     return true;
193 }
194 
SetHardwareResourceToBuffer()195 bool RSRcdSurfaceRenderNode::SetHardwareResourceToBuffer()
196 {
197     RS_LOGD("RCD: Start RSRcdSurfaceRenderNode::SetHardwareResourceToBuffer");
198     if (layerBitmap.IsValid()) {
199         RS_LOGE("LayerBitmap is not valid");
200         return false;
201     }
202     sptr<SurfaceBuffer> nodeBuffer = GetBuffer();
203     if (nodeBuffer == nullptr) {
204         RS_LOGE("RSRcdSurfaceRenderNode buffer is nullptr");
205         return false;
206     }
207     Drawing::ImageInfo imgInfo = Drawing::ImageInfo::MakeN32Premul(nodeBuffer->GetWidth(), nodeBuffer->GetHeight());
208     if (!layerBitmap.ReadPixels(imgInfo, reinterpret_cast<void*>(nodeBuffer->GetVirAddr()),
209         nodeBuffer->GetStride(), 0, 0)) {
210         RS_LOGE("RSRcdSurfaceRenderNode:: copy layerBitmap to buffer failed");
211         return false;
212     }
213     if (!FillHardwareResource(cldLayerInfo, layerBitmap.GetHeight(), layerBitmap.GetWidth())) {
214             RS_LOGE("RSRcdSurfaceRenderNode:: copy hardware resource to buffer failed");
215             return false;
216     }
217     return true;
218 }
219 
FillHardwareResource(HardwareLayerInfo & cldLayerInfo,int height,int width)220 bool RSRcdSurfaceRenderNode::FillHardwareResource(HardwareLayerInfo &cldLayerInfo,
221     int height, int width)
222 {
223     sptr<SurfaceBuffer> nodeBuffer = GetBuffer();
224     if (nodeBuffer == nullptr) {
225         RS_LOGE("RSRcdSurfaceRenderNode buffer is nullptr");
226         return false;
227     }
228     if (cldLayerInfo.bufferSize < 0 || cldLayerInfo.cldWidth < 0 ||
229         cldLayerInfo.cldHeight < 0 || width < 0 || height < 0) {
230         RS_LOGE("RSRcdSurfaceRenderNode check cldLayerInfo and size failed");
231         return false;
232     }
233     const uint32_t bytesPerPixel = 4; // 4 means four bytes per pixel
234     cldInfo_.cldSize = static_cast<uint32_t>(cldLayerInfo.bufferSize);
235     cldInfo_.cldWidth = static_cast<uint32_t>(cldLayerInfo.cldWidth);
236     cldInfo_.cldHeight = static_cast<uint32_t>(cldLayerInfo.cldHeight);
237     cldInfo_.cldStride = static_cast<uint32_t>(cldLayerInfo.cldWidth * bytesPerPixel);
238     cldInfo_.exWidth = static_cast<uint32_t>(width);
239     cldInfo_.exHeight = static_cast<uint32_t>(height);
240 
241     int offset = 0;
242     int offsetCldInfo = 0;
243     int stride = nodeBuffer->GetStride();
244     offsetCldInfo = height * stride;
245     offset = (height + 1) * stride;
246     cldInfo_.cldDataOffset = static_cast<uint32_t>(offset);
247     uint8_t *img = static_cast<uint8_t*>(nodeBuffer->GetVirAddr());
248     uint32_t bufferSize = nodeBuffer->GetSize();
249     if (img == nullptr || offsetCldInfo < 0 || bufferSize < static_cast<uint32_t>(offsetCldInfo) + sizeof(cldInfo_)) {
250         RS_LOGE("[%s] check nodebuffer failed", __func__);
251         return false;
252     }
253     errno_t ret = memcpy_s(reinterpret_cast<void*>(img + offsetCldInfo), sizeof(cldInfo_), &cldInfo_, sizeof(cldInfo_));
254     if (ret != EOK) {
255         RS_LOGE("[%s] memcpy_s failed", __func__);
256         return false;
257     }
258     std::ifstream addBufferFile(cldLayerInfo.pathBin, std::ifstream::binary | std::ifstream::in);
259     if (addBufferFile) {
260         addBufferFile.seekg(0, addBufferFile.end);
261         int addBufferSize = addBufferFile.tellg();
262         addBufferFile.seekg(0, addBufferFile.beg);
263         addBufferFile.read(reinterpret_cast<char*>(img + offset), addBufferSize);
264         addBufferFile.close();
265     } else {
266         RS_LOGE("[%{public}s] hardware fopen error", __func__);
267         return false;
268     }
269     return true;
270 }
271 
IsSurfaceCreated() const272 bool RSRcdSurfaceRenderNode::IsSurfaceCreated() const
273 {
274     return rcdExtInfo_.surfaceCreated;
275 }
276 
277 #ifdef NEW_RENDER_CONTEXT
GetRSSurface() const278 std::shared_ptr<RSRenderSurface> RSRcdSurfaceRenderNode::GetRSSurface() const
279 #else
280 std::shared_ptr<RSSurface> RSRcdSurfaceRenderNode::GetRSSurface() const
281 #endif
282 {
283     return surface_;
284 }
285 
GetConsumerListener() const286 sptr<IBufferConsumerListener> RSRcdSurfaceRenderNode::GetConsumerListener() const
287 {
288     return consumerListener_;
289 }
290 
ClearBufferCache()291 void RSRcdSurfaceRenderNode::ClearBufferCache()
292 {
293     if (surface_ != nullptr) {
294         surface_->ClearBuffer();
295     }
296     if (consumer_ != nullptr) {
297         consumer_->GoBackground();
298     }
299 }
300 
ResetCurrFrameState()301 void RSRcdSurfaceRenderNode::ResetCurrFrameState()
302 {
303     rcdExtInfo_.srcRect_.Clear();
304     rcdExtInfo_.dstRect_.Clear();
305     rcdExtInfo_.surfaceBounds.Clear();
306     rcdExtInfo_.frameBounds.Clear();
307     rcdExtInfo_.frameViewPort.Clear();
308 }
309 
Reset()310 void RSRcdSurfaceRenderNode::Reset()
311 {
312     ResetCurrFrameState();
313 }
314 
IsBottomSurface() const315 bool RSRcdSurfaceRenderNode::IsBottomSurface() const
316 {
317     return rcdExtInfo_.surfaceType == RCDSurfaceType::BOTTOM;
318 }
319 
IsTopSurface() const320 bool RSRcdSurfaceRenderNode::IsTopSurface() const
321 {
322     return rcdExtInfo_.surfaceType == RCDSurfaceType::TOP;
323 }
324 
IsInvalidSurface() const325 bool RSRcdSurfaceRenderNode::IsInvalidSurface() const
326 {
327     return rcdExtInfo_.surfaceType == RCDSurfaceType::INVALID;
328 }
329 
GetSurfaceWidth() const330 float RSRcdSurfaceRenderNode::GetSurfaceWidth() const
331 {
332     return rcdExtInfo_.surfaceBounds.GetWidth();
333 }
334 
GetSurfaceHeight() const335 float RSRcdSurfaceRenderNode::GetSurfaceHeight() const
336 {
337     return rcdExtInfo_.surfaceBounds.GetHeight();
338 }
339 
GetFrameOffsetX() const340 float RSRcdSurfaceRenderNode::GetFrameOffsetX() const
341 {
342     return rcdExtInfo_.GetFrameOffsetX();
343 }
344 
GetFrameOffsetY() const345 float RSRcdSurfaceRenderNode::GetFrameOffsetY() const
346 {
347     return rcdExtInfo_.GetFrameOffsetY();
348 }
349 
GetCldInfo() const350 const CldInfo& RSRcdSurfaceRenderNode::GetCldInfo() const
351 {
352     return cldInfo_;
353 }
354 } // namespace Rosen
355 } // namespace OHOS