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