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