• 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 "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