• 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_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