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