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