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