1 /*
2 * Copyright (c) 2024 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 "pipeline/rs_uni_hwc_prevalidate_util.h"
17
18 #include <dlfcn.h>
19 #include <functional>
20 #include <string>
21
22 #include "rs_base_render_util.h"
23 #include "rs_uni_render_util.h"
24
25 #include "common/rs_common_hook.h"
26 #include "common/rs_obj_abs_geometry.h"
27 #include "drawable/rs_display_render_node_drawable.h"
28 #include "pipeline/rs_surface_render_node.h"
29 #include "pipeline/rs_uifirst_manager.h"
30 #include "platform/common/rs_log.h"
31
32 namespace OHOS {
33 namespace Rosen {
34 constexpr uint32_t ROTATION_360 = 360;
GetInstance()35 RSUniHwcPrevalidateUtil& RSUniHwcPrevalidateUtil::GetInstance()
36 {
37 static RSUniHwcPrevalidateUtil instance;
38 return instance;
39 }
40
RSUniHwcPrevalidateUtil()41 RSUniHwcPrevalidateUtil::RSUniHwcPrevalidateUtil()
42 {
43 preValidateHandle_ = dlopen("libdss_enhance.z.so", RTLD_LAZY);
44 if (preValidateHandle_ == nullptr) {
45 RS_LOGW("[%{public}s_%{public}d]:load library failed, reason: %{public}s", __func__, __LINE__, dlerror());
46 return;
47 }
48 preValidateFunc_ = reinterpret_cast<PreValidateFunc>(dlsym(preValidateHandle_, "RequestLayerStrategy"));
49 if (preValidateFunc_ == nullptr) {
50 RS_LOGW("[%{public}s_%{public}d]:load func failed, reason: %{public}s", __func__, __LINE__, dlerror());
51 dlclose(preValidateHandle_);
52 preValidateHandle_ = nullptr;
53 return;
54 }
55 RS_LOGI("[%{public}s_%{public}d]:load success", __func__, __LINE__);
56 loadSuccess = true;
57 arsrPreEnabled_ = RSSystemParameters::GetArsrPreEnabled();
58 }
59
~RSUniHwcPrevalidateUtil()60 RSUniHwcPrevalidateUtil::~RSUniHwcPrevalidateUtil()
61 {
62 if (preValidateHandle_) {
63 dlclose(preValidateHandle_);
64 preValidateHandle_ = nullptr;
65 }
66 }
67
IsLoadSuccess() const68 bool RSUniHwcPrevalidateUtil::IsLoadSuccess() const
69 {
70 return loadSuccess;
71 }
72
PreValidate(ScreenId id,std::vector<RequestLayerInfo> infos,std::map<uint64_t,RequestCompositionType> & strategy)73 bool RSUniHwcPrevalidateUtil::PreValidate(
74 ScreenId id, std::vector<RequestLayerInfo> infos, std::map<uint64_t, RequestCompositionType> &strategy)
75 {
76 if (!preValidateFunc_) {
77 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::PreValidate preValidateFunc is null");
78 ClearCldInfo(infos);
79 return false;
80 }
81 int32_t ret = preValidateFunc_(id, infos, strategy);
82 ClearCldInfo(infos);
83 return ret == 0;
84 }
85
ClearCldInfo(std::vector<RequestLayerInfo> & infos)86 void RSUniHwcPrevalidateUtil::ClearCldInfo(std::vector<RequestLayerInfo>& infos)
87 {
88 for (auto& info: infos) {
89 if (info.cldInfo != nullptr) {
90 delete info.cldInfo;
91 info.cldInfo = nullptr;
92 }
93 }
94 }
95
CreateSurfaceNodeLayerInfo(uint32_t zorder,RSSurfaceRenderNode::SharedPtr node,GraphicTransformType transform,uint32_t fps,RequestLayerInfo & info)96 bool RSUniHwcPrevalidateUtil::CreateSurfaceNodeLayerInfo(uint32_t zorder,
97 RSSurfaceRenderNode::SharedPtr node, GraphicTransformType transform, uint32_t fps, RequestLayerInfo &info)
98 {
99 if (!node || !node->GetRSSurfaceHandler()->GetConsumer() || !node->GetRSSurfaceHandler()->GetBuffer()) {
100 return false;
101 }
102 info.id = node->GetId();
103 auto src = node->GetSrcRect();
104 info.srcRect = {src.left_, src.top_, src.width_, src.height_};
105 auto dst = node->GetDstRect();
106 info.dstRect = {dst.left_, dst.top_, dst.width_, dst.height_};
107 info.zOrder = zorder;
108 info.usage = node->GetRSSurfaceHandler()->GetBuffer()->GetUsage();
109 info.format = node->GetRSSurfaceHandler()->GetBuffer()->GetFormat();
110 info.fps = fps;
111 info.transform = static_cast<int>(transform);
112
113 if (RsCommonHook::Instance().GetVideoSurfaceFlag() && IsYUVBufferFormat(node)) {
114 info.perFrameParameters["SourceCropTuning"] = std::vector<int8_t> {1};
115 } else {
116 info.perFrameParameters["SourceCropTuning"] = std::vector<int8_t> {0};
117 }
118
119 if (arsrPreEnabled_ && CheckIfDoArsrPre(node)) {
120 info.perFrameParameters["ArsrDoEnhance"] = std::vector<int8_t> {1};
121 node->SetArsrTag(true);
122 }
123 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateSurfaceNodeLayerInfo %{public}s,"
124 " %{public}" PRIu64 ", src: %{public}s, dst: %{public}s, z: %{public}" PRIu32 ","
125 " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
126 node->GetName().c_str(), node->GetId(),
127 node->GetSrcRect().ToString().c_str(), node->GetDstRect().ToString().c_str(),
128 zorder, info.usage, info.format, info.transform, fps);
129 return true;
130 }
131
IsYUVBufferFormat(RSSurfaceRenderNode::SharedPtr node) const132 bool RSUniHwcPrevalidateUtil::IsYUVBufferFormat(RSSurfaceRenderNode::SharedPtr node) const
133 {
134 if (node->GetRSSurfaceHandler()->GetBuffer() == nullptr) {
135 return false;
136 }
137 auto format = node->GetRSSurfaceHandler()->GetBuffer()->GetFormat();
138 if (format < GRAPHIC_PIXEL_FMT_YUV_422_I || format == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
139 format > GRAPHIC_PIXEL_FMT_YCRCB_P010) {
140 return false;
141 }
142 return true;
143 }
144
CreateDisplayNodeLayerInfo(uint32_t zorder,RSDisplayRenderNode::SharedPtr node,const ScreenInfo & screenInfo,uint32_t fps,RequestLayerInfo & info)145 bool RSUniHwcPrevalidateUtil::CreateDisplayNodeLayerInfo(uint32_t zorder,
146 RSDisplayRenderNode::SharedPtr node, const ScreenInfo &screenInfo, uint32_t fps, RequestLayerInfo &info)
147 {
148 if (!node) {
149 return false;
150 }
151 auto drawable = node->GetRenderDrawable();
152 if (!drawable) {
153 return false;
154 }
155 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
156 auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
157 if (!surfaceHandler->GetConsumer() || !surfaceHandler->GetBuffer()) {
158 return false;
159 }
160 auto buffer = surfaceHandler->GetBuffer();
161 info.id = node->GetId();
162 info.srcRect = {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
163 info.dstRect = {0, 0, screenInfo.GetRotatedPhyWidth(), screenInfo.GetRotatedPhyHeight()};
164 info.zOrder = zorder;
165 info.usage = buffer->GetUsage() | USAGE_UNI_LAYER;
166 info.format = buffer->GetFormat();
167 info.fps = fps;
168 LayerRotate(info, surfaceHandler->GetConsumer(), screenInfo);
169 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateDisplayNodeLayerInfo %{public}" PRIu64 ","
170 " src: %{public}d,%{public}d,%{public}d,%{public}d"
171 " dst: %{public}d,%{public}d,%{public}d,%{public}d, z: %{public}" PRIu32 ","
172 " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
173 node->GetId(), info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
174 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
175 zorder, info.usage, info.format, info.transform, fps);
176 return true;
177 }
178
CreateUIFirstLayerInfo(RSSurfaceRenderNode::SharedPtr node,GraphicTransformType transform,uint32_t fps,RequestLayerInfo & info)179 bool RSUniHwcPrevalidateUtil::CreateUIFirstLayerInfo(
180 RSSurfaceRenderNode::SharedPtr node, GraphicTransformType transform, uint32_t fps, RequestLayerInfo &info)
181 {
182 if (!node) {
183 return false;
184 }
185 info.id = node->GetId();
186 auto src = node->GetSrcRect();
187 info.srcRect = {src.left_, src.top_, src.width_, src.height_};
188 auto dst = node->GetDstRect();
189 info.dstRect = {dst.left_, dst.top_, dst.width_, dst.height_};
190 info.zOrder = static_cast<uint32_t>(node->GetRSSurfaceHandler()->GetGlobalZOrder());
191 info.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
192 info.usage = BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_HW_COMPOSER | BUFFER_USAGE_MEM_DMA;
193 info.fps = fps;
194 info.transform = static_cast<int>(transform);
195 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateUIFirstLayerInfo %{public}s, %{public}" PRIu64 ","
196 " src: %{public}s, dst: %{public}s, z: %{public}" PRIu32 ","
197 " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
198 node->GetName().c_str(), node->GetId(),
199 node->GetSrcRect().ToString().c_str(), node->GetDstRect().ToString().c_str(),
200 info.zOrder, info.usage, info.format, info.transform, fps);
201 return true;
202 }
203
CreateRCDLayerInfo(RSRcdSurfaceRenderNode::SharedPtr node,const ScreenInfo & screenInfo,uint32_t fps,RequestLayerInfo & info)204 bool RSUniHwcPrevalidateUtil::CreateRCDLayerInfo(
205 RSRcdSurfaceRenderNode::SharedPtr node, const ScreenInfo &screenInfo, uint32_t fps, RequestLayerInfo &info)
206 {
207 if (!node || !node->GetConsumer() || !node->GetBuffer()) {
208 return false;
209 }
210
211 info.id = node->GetId();
212 auto src = node->GetSrcRect();
213 info.srcRect = {src.left_, src.top_, src.width_, src.height_};
214 auto dst = node->GetDstRect();
215 info.dstRect.x = static_cast<uint32_t>(static_cast<float>(dst.left_) * screenInfo.GetRogWidthRatio());
216 info.dstRect.y = static_cast<uint32_t>(static_cast<float>(dst.top_) * screenInfo.GetRogHeightRatio());
217 info.dstRect.w = static_cast<uint32_t>(static_cast<float>(dst.width_) * screenInfo.GetRogWidthRatio());
218 info.dstRect.h = static_cast<uint32_t>(static_cast<float>(dst.height_) * screenInfo.GetRogHeightRatio());
219 info.zOrder = static_cast<uint32_t>(node->GetGlobalZOrder());
220 info.usage = node->GetBuffer()->GetUsage();
221 info.format = node->GetBuffer()->GetFormat();
222 info.fps = fps;
223 CopyCldInfo(node->GetCldInfo(), info);
224 LayerRotate(info, node->GetConsumer(), screenInfo);
225 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateRCDLayerInfo %{public}" PRIu64 ","
226 " src: %{public}d,%{public}d,%{public}d,%{public}d"
227 " dst: %{public}d,%{public}d,%{public}d,%{public}d, z: %{public}" PRIu32 ","
228 " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
229 node->GetId(),
230 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
231 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
232 info.zOrder, info.usage, info.format, info.transform, fps);
233 return true;
234 }
235
CollectSurfaceNodeLayerInfo(std::vector<RequestLayerInfo> & prevalidLayers,std::vector<RSBaseRenderNode::SharedPtr> & surfaceNodes,uint32_t curFps,uint32_t & zOrder,const ScreenInfo & screenInfo)236 void RSUniHwcPrevalidateUtil::CollectSurfaceNodeLayerInfo(
237 std::vector<RequestLayerInfo>& prevalidLayers, std::vector<RSBaseRenderNode::SharedPtr>& surfaceNodes,
238 uint32_t curFps, uint32_t &zOrder, const ScreenInfo& screenInfo)
239 {
240 for (auto it = surfaceNodes.rbegin(); it != surfaceNodes.rend(); it++) {
241 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
242 if (!surfaceNode) {
243 continue;
244 }
245 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
246 if (hwcNodes.empty()) {
247 continue;
248 }
249 for (auto& hwcNode : hwcNodes) {
250 auto hwcNodePtr = hwcNode.lock();
251 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->IsHardwareForcedDisabled()
252 || hwcNodePtr->GetAncoForceDoDirect()) {
253 continue;
254 }
255 auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo);
256 RequestLayerInfo surfaceLayer;
257 if (RSUniHwcPrevalidateUtil::GetInstance().CreateSurfaceNodeLayerInfo(
258 zOrder++, hwcNodePtr, transform, curFps, surfaceLayer)) {
259 prevalidLayers.emplace_back(surfaceLayer);
260 }
261 }
262 }
263 }
264
CollectUIFirstLayerInfo(std::vector<RequestLayerInfo> & uiFirstLayers,uint32_t curFps,float zOrder,const ScreenInfo & screenInfo)265 void RSUniHwcPrevalidateUtil::CollectUIFirstLayerInfo(std::vector<RequestLayerInfo>& uiFirstLayers,
266 uint32_t curFps, float zOrder, const ScreenInfo& screenInfo)
267 {
268 auto pendingNodes = RSUifirstManager::Instance().GetPendingPostNodes();
269 for (auto iter : pendingNodes) {
270 if (!iter.second || iter.second->IsHardwareForcedDisabled() ||
271 !RSUifirstManager::Instance().GetUseDmaBuffer(iter.second->GetName())) {
272 continue;
273 }
274 iter.second->GetMutableRSSurfaceHandler()->SetGlobalZOrder(zOrder++);
275 auto transform = RSUniRenderUtil::GetLayerTransform(*iter.second, screenInfo);
276 RequestLayerInfo uiFirstLayer;
277 if (RSUniHwcPrevalidateUtil::GetInstance().CreateUIFirstLayerInfo(
278 iter.second, transform, curFps, uiFirstLayer)) {
279 uiFirstLayers.emplace_back(uiFirstLayer);
280 }
281 }
282 }
283
LayerRotate(RequestLayerInfo & info,const sptr<IConsumerSurface> & surface,const ScreenInfo & screenInfo)284 void RSUniHwcPrevalidateUtil::LayerRotate(
285 RequestLayerInfo& info, const sptr<IConsumerSurface>& surface, const ScreenInfo &screenInfo)
286 {
287 if (!surface) {
288 return;
289 }
290 const auto screenWidth = static_cast<int32_t>(screenInfo.width);
291 const auto screenHeight = static_cast<int32_t>(screenInfo.height);
292 const auto screenRotation = screenInfo.rotation;
293 const auto rect = info.dstRect;
294 switch (screenRotation) {
295 case ScreenRotation::ROTATION_90: {
296 info.dstRect = {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w};
297 break;
298 }
299 case ScreenRotation::ROTATION_180: {
300 info.dstRect = {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h};
301 break;
302 }
303 case ScreenRotation::ROTATION_270: {
304 info.dstRect = {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w};
305 break;
306 }
307 default: {
308 break;
309 }
310 }
311 int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenRotation) + RSBaseRenderUtil::RotateEnumToInt(
312 RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()))) % ROTATION_360;
313 GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation,
314 RSBaseRenderUtil::GetFlipTransform(surface->GetTransform()));
315 info.transform = rotateEnum;
316 }
317
CopyCldInfo(CldInfo src,RequestLayerInfo & info)318 void RSUniHwcPrevalidateUtil::CopyCldInfo(CldInfo src, RequestLayerInfo& info)
319 {
320 info.cldInfo = new CldInfo();
321 info.cldInfo->cldDataOffset = src.cldDataOffset;
322 info.cldInfo->cldSize = src.cldSize;
323 info.cldInfo->cldWidth = src.cldWidth;
324 info.cldInfo->cldHeight = src.cldHeight;
325 info.cldInfo->cldStride = src.cldStride;
326 info.cldInfo->exWidth = src.exWidth;
327 info.cldInfo->exHeight = src.exHeight;
328 info.cldInfo->baseColor = src.baseColor;
329 }
330
CheckIfDoArsrPre(const RSSurfaceRenderNode::SharedPtr node)331 bool RSUniHwcPrevalidateUtil::CheckIfDoArsrPre(const RSSurfaceRenderNode::SharedPtr node)
332 {
333 if (node->GetRSSurfaceHandler()->GetBuffer() == nullptr) {
334 return false;
335 }
336 static const std::unordered_set<std::string> videoLayers {
337 "xcomponentIdSurface",
338 "componentIdSurface",
339 "SceneViewer Model totemweather0",
340 };
341 if (IsYUVBufferFormat(node) || (videoLayers.count(node->GetName()) > 0)) {
342 return true;
343 }
344 return false;
345 }
346 } //Rosen
347 } //OHOS