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_anco_manager.h"
17
18 #include <parameters.h>
19 #include "param/sys_param.h"
20 #include "params/rs_surface_render_params.h"
21 #include "platform/common/rs_system_properties.h"
22
23 namespace OHOS::Rosen {
Instance()24 RSAncoManager* RSAncoManager::Instance()
25 {
26 static RSAncoManager instance;
27 return &instance;
28 }
29
AncoDisableHebcProperty()30 static bool AncoDisableHebcProperty()
31 {
32 // Dynamically disable unified rendering layer hebc if persist.sys.graphic.anco.disableHebc equal 1
33 static bool result =
34 std::atoi((system::GetParameter("persist.sys.graphic.anco.disableHebc", "0")).c_str()) != 0;
35 return result;
36 }
37
GetAncoHebcStatus() const38 AncoHebcStatus RSAncoManager::GetAncoHebcStatus() const
39 {
40 if (!AncoDisableHebcProperty()) {
41 return AncoHebcStatus::INITIAL;
42 }
43 return static_cast<AncoHebcStatus>(ancoHebcStatus_.load());
44 }
45
SetAncoHebcStatus(AncoHebcStatus hebcStatus)46 void RSAncoManager::SetAncoHebcStatus(AncoHebcStatus hebcStatus)
47 {
48 ancoHebcStatus_.store(static_cast<int32_t>(hebcStatus));
49 }
50
AncoOptimizeCheck(bool isHebc,int nodesCnt,int sfvNodesCnt)51 bool RSAncoManager::AncoOptimizeCheck(bool isHebc, int nodesCnt, int sfvNodesCnt)
52 {
53 constexpr int minOptimizeAncoNums = 3;
54 constexpr int minOptimizeAncoSfvNums = 2;
55 bool numsMatch = nodesCnt == minOptimizeAncoNums && sfvNodesCnt == minOptimizeAncoSfvNums;
56 if (numsMatch && isHebc) {
57 RS_LOGI("doDirect anco disable hebc");
58 SetAncoHebcStatus(AncoHebcStatus::NOT_USE_HEBC);
59 return true;
60 }
61 if (!numsMatch && !isHebc) {
62 RS_LOGI("doDirect anco enable hebc");
63 SetAncoHebcStatus(AncoHebcStatus::USE_HEBC);
64 return true;
65 }
66 return false;
67 }
68
IsAncoOptimize(ScreenRotation rotation)69 bool RSAncoManager::IsAncoOptimize(ScreenRotation rotation)
70 {
71 if (!AncoDisableHebcProperty() || !RSSurfaceRenderNode::GetOriAncoForceDoDirect() ||
72 rotation != ScreenRotation::ROTATION_0) {
73 return false;
74 }
75 return true;
76 }
77
AncoOptimizeDisplayNode(std::shared_ptr<RSSurfaceHandler> & surfaceHandler,std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hardwareEnabledNodes,ScreenRotation rotation,uint32_t width,uint32_t height)78 bool RSAncoManager::AncoOptimizeDisplayNode(std::shared_ptr<RSSurfaceHandler>& surfaceHandler,
79 std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes,
80 ScreenRotation rotation, uint32_t width, uint32_t height)
81 {
82 SetAncoHebcStatus(AncoHebcStatus::INITIAL);
83 if (!IsAncoOptimize(rotation)) {
84 return false;
85 }
86
87 if (surfaceHandler == nullptr || surfaceHandler->GetBuffer() == nullptr) {
88 return false;
89 }
90 bool isHebc = true;
91 if ((surfaceHandler->GetBuffer()->GetUsage() & BUFFER_USAGE_CPU_READ) ||
92 (surfaceHandler->GetBuffer()->GetUsage() & BUFFER_USAGE_CPU_WRITE)) {
93 isHebc = false;
94 }
95
96 // process displayNode rect
97 uint32_t minArea = width * height / 2;
98 if (minArea == 0) {
99 return false;
100 }
101
102 int nodesCnt = 0;
103 int sfvNodesCnt = 0;
104 for (auto& surfaceNode : hardwareEnabledNodes) {
105 if ((surfaceNode->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) == 0) {
106 continue;
107 }
108 auto alpha = surfaceNode->GetGlobalAlpha();
109 if (ROSEN_EQ(alpha, 0.0f) || !surfaceNode->GetRSSurfaceHandler() ||
110 !surfaceNode->GetRSSurfaceHandler()->GetBuffer()) {
111 continue;
112 }
113 #ifdef RS_ENABLE_GPU
114 auto params = static_cast<RSSurfaceRenderParams*>(surfaceNode->GetStagingRenderParams().get());
115 if (params == nullptr) {
116 continue;
117 }
118 auto& layerInfo = params->GetLayerInfo().dstRect;
119 if (layerInfo.w <= 0 || layerInfo.h <= 0) {
120 continue;
121 }
122 if (static_cast<uint32_t>(layerInfo.w * layerInfo.h) >= minArea) {
123 nodesCnt++;
124 if (surfaceNode->GetAncoFlags() == static_cast<uint32_t>(AncoFlags::ANCO_SFV_NODE)) {
125 sfvNodesCnt++;
126 }
127 }
128 #endif
129 }
130
131 return AncoOptimizeCheck(isHebc, nodesCnt, sfvNodesCnt);
132 }
133 } // namespace OHOS::Rosen
134