• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     auto dst = node->GetDstRect();
105     Rect crop{0, 0, 0, 0};
106     auto buffer = node->GetRSSurfaceHandler()->GetBuffer();
107     if (buffer->GetCropMetadata(crop)) {
108         float scaleX = static_cast<float>(crop.w) / buffer->GetWidth();
109         float scaleY = static_cast<float>(crop.h) / buffer->GetHeight();
110         info.srcRect = {
111             static_cast<uint32_t>(std::ceil(src.left_ * scaleX)),
112             static_cast<uint32_t>(std::ceil(src.top_ * scaleY)),
113             static_cast<uint32_t>(std::floor(src.width_ * scaleX)),
114             static_cast<uint32_t>(std::floor(src.height_ * scaleY))
115         };
116     } else {
117         info.srcRect = {src.left_, src.top_, src.width_, src.height_};
118     }
119     info.dstRect = {dst.left_, dst.top_, dst.width_, dst.height_};
120     info.zOrder = zorder;
121     info.usage = node->GetRSSurfaceHandler()->GetBuffer()->GetUsage();
122     info.format = node->GetRSSurfaceHandler()->GetBuffer()->GetFormat();
123     info.fps = fps;
124     info.transform = static_cast<int>(transform);
125 
126     if (RsCommonHook::Instance().GetVideoSurfaceFlag() && IsYUVBufferFormat(node)) {
127         info.perFrameParameters["SourceCropTuning"] = std::vector<int8_t> {1};
128     } else {
129         info.perFrameParameters["SourceCropTuning"] = std::vector<int8_t> {0};
130     }
131 
132     if (arsrPreEnabled_ && CheckIfDoArsrPre(node)) {
133         info.perFrameParameters["ArsrDoEnhance"] = std::vector<int8_t> {1};
134         node->SetArsrTag(true);
135     }
136     RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateSurfaceNodeLayerInfo %{public}s,"
137         " %{public}" PRIu64 ", src: %{public}s, dst: %{public}s, z: %{public}" PRIu32 ","
138         " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
139         node->GetName().c_str(), node->GetId(),
140         node->GetSrcRect().ToString().c_str(), node->GetDstRect().ToString().c_str(),
141         zorder, info.usage, info.format, info.transform, fps);
142     return true;
143 }
144 
IsYUVBufferFormat(RSSurfaceRenderNode::SharedPtr node) const145 bool RSUniHwcPrevalidateUtil::IsYUVBufferFormat(RSSurfaceRenderNode::SharedPtr node) const
146 {
147     if (node->GetRSSurfaceHandler()->GetBuffer() == nullptr) {
148         return false;
149     }
150     auto format = node->GetRSSurfaceHandler()->GetBuffer()->GetFormat();
151     if (format < GRAPHIC_PIXEL_FMT_YUV_422_I || format == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
152         format > GRAPHIC_PIXEL_FMT_YCRCB_P010) {
153         return false;
154     }
155     return true;
156 }
157 
CreateDisplayNodeLayerInfo(uint32_t zorder,RSDisplayRenderNode::SharedPtr node,const ScreenInfo & screenInfo,uint32_t fps,RequestLayerInfo & info)158 bool RSUniHwcPrevalidateUtil::CreateDisplayNodeLayerInfo(uint32_t zorder,
159     RSDisplayRenderNode::SharedPtr node, const ScreenInfo &screenInfo, uint32_t fps, RequestLayerInfo &info)
160 {
161     if (!node) {
162         return false;
163     }
164     auto drawable = node->GetRenderDrawable();
165     if (!drawable) {
166         return false;
167     }
168     auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
169     auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
170     if (!surfaceHandler->GetConsumer() || !surfaceHandler->GetBuffer()) {
171         return false;
172     }
173     auto buffer = surfaceHandler->GetBuffer();
174     info.id = node->GetId();
175     info.srcRect = {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
176     info.dstRect = {0, 0, screenInfo.GetRotatedPhyWidth(), screenInfo.GetRotatedPhyHeight()};
177     info.zOrder = zorder;
178     info.usage = buffer->GetUsage() | USAGE_UNI_LAYER;
179     info.format = buffer->GetFormat();
180     info.fps = fps;
181     LayerRotate(info, surfaceHandler->GetConsumer(), screenInfo);
182     RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateDisplayNodeLayerInfo %{public}" PRIu64 ","
183         " src: %{public}d,%{public}d,%{public}d,%{public}d"
184         " dst: %{public}d,%{public}d,%{public}d,%{public}d, z: %{public}" PRIu32 ","
185         " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
186         node->GetId(), info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
187         info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
188         zorder, info.usage, info.format, info.transform, fps);
189     return true;
190 }
191 
CreateUIFirstLayerInfo(RSSurfaceRenderNode::SharedPtr node,GraphicTransformType transform,uint32_t fps,RequestLayerInfo & info)192 bool RSUniHwcPrevalidateUtil::CreateUIFirstLayerInfo(
193     RSSurfaceRenderNode::SharedPtr node, GraphicTransformType transform, uint32_t fps, RequestLayerInfo &info)
194 {
195     if (!node) {
196         return false;
197     }
198     info.id = node->GetId();
199     auto src = node->GetSrcRect();
200     info.srcRect = {src.left_, src.top_, src.width_, src.height_};
201     auto dst = node->GetDstRect();
202     info.dstRect = {dst.left_, dst.top_, dst.width_, dst.height_};
203     info.zOrder = static_cast<uint32_t>(node->GetRSSurfaceHandler()->GetGlobalZOrder());
204     info.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
205     info.usage = BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_HW_COMPOSER | BUFFER_USAGE_MEM_DMA;
206     info.fps = fps;
207     info.transform = static_cast<int>(transform);
208     RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateUIFirstLayerInfo %{public}s, %{public}" PRIu64 ","
209         " src: %{public}s, dst: %{public}s, z: %{public}" PRIu32 ","
210         " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
211         node->GetName().c_str(), node->GetId(),
212         node->GetSrcRect().ToString().c_str(), node->GetDstRect().ToString().c_str(),
213         info.zOrder, info.usage, info.format, info.transform, fps);
214     return true;
215 }
216 
CreateRCDLayerInfo(RSRcdSurfaceRenderNode::SharedPtr node,const ScreenInfo & screenInfo,uint32_t fps,RequestLayerInfo & info)217 bool RSUniHwcPrevalidateUtil::CreateRCDLayerInfo(
218     RSRcdSurfaceRenderNode::SharedPtr node, const ScreenInfo &screenInfo, uint32_t fps, RequestLayerInfo &info)
219 {
220     if (!node || !node->GetConsumer() || !node->GetBuffer()) {
221         return false;
222     }
223 
224     info.id = node->GetId();
225     auto src = node->GetSrcRect();
226     info.srcRect = {src.left_, src.top_, src.width_, src.height_};
227     auto dst = node->GetDstRect();
228     info.dstRect.x = static_cast<uint32_t>(static_cast<float>(dst.left_) * screenInfo.GetRogWidthRatio());
229     info.dstRect.y = static_cast<uint32_t>(static_cast<float>(dst.top_) * screenInfo.GetRogHeightRatio());
230     info.dstRect.w = static_cast<uint32_t>(static_cast<float>(dst.width_) * screenInfo.GetRogWidthRatio());
231     info.dstRect.h = static_cast<uint32_t>(static_cast<float>(dst.height_) * screenInfo.GetRogHeightRatio());
232     info.zOrder = static_cast<uint32_t>(node->GetGlobalZOrder());
233     info.usage = node->GetBuffer()->GetUsage();
234     info.format = node->GetBuffer()->GetFormat();
235     info.fps = fps;
236     CopyCldInfo(node->GetCldInfo(), info);
237     LayerRotate(info, node->GetConsumer(), screenInfo);
238     RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniHwcPrevalidateUtil::CreateRCDLayerInfo %{public}" PRIu64 ","
239         " src: %{public}d,%{public}d,%{public}d,%{public}d"
240         " dst: %{public}d,%{public}d,%{public}d,%{public}d, z: %{public}" PRIu32 ","
241         " usage: %{public}" PRIu64 ", format: %{public}d, transform: %{public}d, fps: %{public}d",
242         node->GetId(),
243         info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
244         info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
245         info.zOrder, info.usage, info.format, info.transform, fps);
246     return true;
247 }
248 
CollectSurfaceNodeLayerInfo(std::vector<RequestLayerInfo> & prevalidLayers,std::vector<RSBaseRenderNode::SharedPtr> & surfaceNodes,uint32_t curFps,uint32_t & zOrder,const ScreenInfo & screenInfo)249 void RSUniHwcPrevalidateUtil::CollectSurfaceNodeLayerInfo(
250     std::vector<RequestLayerInfo>& prevalidLayers, std::vector<RSBaseRenderNode::SharedPtr>& surfaceNodes,
251     uint32_t curFps, uint32_t &zOrder, const ScreenInfo& screenInfo)
252 {
253     for (auto it = surfaceNodes.rbegin(); it != surfaceNodes.rend(); it++) {
254         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
255         if (!surfaceNode) {
256             continue;
257         }
258         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
259         if (hwcNodes.empty()) {
260             continue;
261         }
262         for (auto& hwcNode : hwcNodes) {
263             auto hwcNodePtr = hwcNode.lock();
264             if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->IsHardwareForcedDisabled()
265                 || hwcNodePtr->GetAncoForceDoDirect()) {
266                 continue;
267             }
268             auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo);
269             RequestLayerInfo surfaceLayer;
270             if (RSUniHwcPrevalidateUtil::GetInstance().CreateSurfaceNodeLayerInfo(
271                 zOrder++, hwcNodePtr, transform, curFps, surfaceLayer)) {
272                 prevalidLayers.emplace_back(surfaceLayer);
273             }
274         }
275     }
276 }
277 
CollectUIFirstLayerInfo(std::vector<RequestLayerInfo> & uiFirstLayers,uint32_t curFps,float zOrder,const ScreenInfo & screenInfo)278 void RSUniHwcPrevalidateUtil::CollectUIFirstLayerInfo(std::vector<RequestLayerInfo>& uiFirstLayers,
279     uint32_t curFps, float zOrder, const ScreenInfo& screenInfo)
280 {
281     auto pendingNodes = RSUifirstManager::Instance().GetPendingPostNodes();
282     for (auto iter : pendingNodes) {
283         if (!iter.second || iter.second->IsHardwareForcedDisabled() ||
284             !RSUifirstManager::Instance().GetUseDmaBuffer(iter.second->GetName())) {
285             continue;
286         }
287         iter.second->GetMutableRSSurfaceHandler()->SetGlobalZOrder(zOrder++);
288         auto transform = RSUniRenderUtil::GetLayerTransform(*iter.second, screenInfo);
289         RequestLayerInfo uiFirstLayer;
290         if (RSUniHwcPrevalidateUtil::GetInstance().CreateUIFirstLayerInfo(
291             iter.second, transform, curFps, uiFirstLayer)) {
292             uiFirstLayers.emplace_back(uiFirstLayer);
293         }
294     }
295 }
296 
LayerRotate(RequestLayerInfo & info,const sptr<IConsumerSurface> & surface,const ScreenInfo & screenInfo)297 void RSUniHwcPrevalidateUtil::LayerRotate(
298     RequestLayerInfo& info, const sptr<IConsumerSurface>& surface, const ScreenInfo &screenInfo)
299 {
300     if (!surface) {
301         return;
302     }
303     const auto screenWidth = static_cast<int32_t>(screenInfo.width);
304     const auto screenHeight = static_cast<int32_t>(screenInfo.height);
305     const auto screenRotation = screenInfo.rotation;
306     const auto rect = info.dstRect;
307     switch (screenRotation) {
308         case ScreenRotation::ROTATION_90: {
309             info.dstRect = {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w};
310             break;
311         }
312         case ScreenRotation::ROTATION_180: {
313             info.dstRect = {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h};
314             break;
315         }
316         case ScreenRotation::ROTATION_270: {
317             info.dstRect = {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w};
318             break;
319         }
320         default: {
321             break;
322         }
323     }
324     int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenRotation) + RSBaseRenderUtil::RotateEnumToInt(
325         RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()))) % ROTATION_360;
326     GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation,
327         RSBaseRenderUtil::GetFlipTransform(surface->GetTransform()));
328     info.transform = rotateEnum;
329 }
330 
CopyCldInfo(CldInfo src,RequestLayerInfo & info)331 void RSUniHwcPrevalidateUtil::CopyCldInfo(CldInfo src, RequestLayerInfo& info)
332 {
333     info.cldInfo = new CldInfo();
334     info.cldInfo->cldDataOffset = src.cldDataOffset;
335     info.cldInfo->cldSize = src.cldSize;
336     info.cldInfo->cldWidth = src.cldWidth;
337     info.cldInfo->cldHeight = src.cldHeight;
338     info.cldInfo->cldStride = src.cldStride;
339     info.cldInfo->exWidth = src.exWidth;
340     info.cldInfo->exHeight = src.exHeight;
341     info.cldInfo->baseColor = src.baseColor;
342 }
343 
CheckIfDoArsrPre(const RSSurfaceRenderNode::SharedPtr node)344 bool RSUniHwcPrevalidateUtil::CheckIfDoArsrPre(const RSSurfaceRenderNode::SharedPtr node)
345 {
346     if (node->GetRSSurfaceHandler()->GetBuffer() == nullptr) {
347         return false;
348     }
349     static const std::unordered_set<std::string> videoLayers {
350         "xcomponentIdSurface",
351         "componentIdSurface",
352         "SceneViewer Model totemweather0",
353     };
354     if (IsYUVBufferFormat(node) || (videoLayers.count(node->GetName()) > 0)) {
355         return true;
356     }
357     return false;
358 }
359 } //Rosen
360 } //OHOS