• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_processor.h"
17 
18 #include "common/rs_obj_abs_geometry.h"
19 #include "platform/common/rs_log.h"
20 #include "rs_base_render_util.h"
21 #include "rs_main_thread.h"
22 #ifdef SOC_PERF_ENABLE
23 #include "socperf_client.h"
24 #endif
25 #ifdef FRAME_AWARE_TRACE
26 #include "render_frame_trace.h"
27 
28 using namespace FRAME_TRACE;
29 #endif
30 
31 namespace OHOS {
32 namespace Rosen {
33 bool RSProcessor::needDisableMultiLayersPerf_ = false;
34 namespace {
35 constexpr uint32_t PERF_LEVEL_0 = 0;
36 constexpr uint32_t PERF_LEVEL_1 = 1;
37 constexpr uint32_t PERF_LEVEL_2 = 2;
38 constexpr int32_t PERF_LEVEL_1_REQUESTED_CODE = 10013;
39 constexpr int32_t PERF_LEVEL_2_REQUESTED_CODE = 10014;
40 constexpr int32_t PERF_LEVEL_3_REQUESTED_CODE = 10015;
41 constexpr int64_t PERF_TIME_OUT = 950;
42 constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
43 constexpr uint32_t PERF_LAYER_START_NUM = 12;
44 #ifdef FRAME_AWARE_TRACE
45 constexpr uint32_t FRAME_TRACE_LAYER_NUM_1 = 11;
46 constexpr uint32_t FRAME_TRACE_LAYER_NUM_2 = 13;
47 constexpr int32_t FRAME_TRACE_PERF_REQUESTED_CODE = 10024;
48 #endif
49 
PerfRequest(int32_t perfRequestCode,bool onOffTag)50 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
51 {
52 #ifdef SOC_PERF_ENABLE
53     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
54     RS_LOGD("RSProcessor::soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
55 #endif
56 }
57 }
58 
59 #ifdef FRAME_AWARE_TRACE
FrameAwareTraceBoost(size_t layerNum)60 bool RSProcessor::FrameAwareTraceBoost(size_t layerNum)
61 {
62     RenderFrameTrace& ft = RenderFrameTrace::GetInstance();
63     if (layerNum != FRAME_TRACE_LAYER_NUM_1 && layerNum != FRAME_TRACE_LAYER_NUM_2) {
64         if (ft.RenderFrameTraceIsOpen()) {
65             ft.RenderFrameTraceClose();
66             PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, false);
67             RS_LOGD("RsDebug RSProcessor::Perf: FrameTrace 0");
68         }
69         return false;
70     }
71 
72     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
73     auto currentTime = std::chrono::steady_clock::now();
74     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
75         count() > PERF_TIME_OUT;
76     if (isTimeOut || !ft.RenderFrameTraceIsOpen()) {
77         if (!ft.RenderFrameTraceOpen()) {
78             return false;
79         }
80         PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, true);
81         RS_LOGD("RsDebug RSProcessor::Perf: FrameTrace 1");
82         lastRequestPerfTime = currentTime;
83     }
84     return true;
85 }
86 #endif
87 
RequestPerf(uint32_t layerLevel,bool onOffTag)88 void RSProcessor::RequestPerf(uint32_t layerLevel, bool onOffTag)
89 {
90     switch (layerLevel) {
91         case PERF_LEVEL_0: {
92             // do nothing
93             RS_LOGD("RsDebug RSProcessor::Perf: perf do nothing");
94             break;
95         }
96         case PERF_LEVEL_1: {
97             PerfRequest(PERF_LEVEL_1_REQUESTED_CODE, onOffTag);
98             RS_LOGD("RsDebug RSProcessor::Perf: level1 %{public}d", onOffTag);
99             break;
100         }
101         case PERF_LEVEL_2: {
102             PerfRequest(PERF_LEVEL_2_REQUESTED_CODE, onOffTag);
103             RS_LOGD("RsDebug RSProcessor::Perf: level2 %{public}d", onOffTag);
104             break;
105         }
106         default: {
107             PerfRequest(PERF_LEVEL_3_REQUESTED_CODE, onOffTag);
108             RS_LOGD("RsDebug RSProcessor::Perf: level3 %{public}d", onOffTag);
109             break;
110         }
111     }
112 }
113 
Init(RSDisplayRenderNode & node,int32_t offsetX,int32_t offsetY,ScreenId mirroredId,std::shared_ptr<RSBaseRenderEngine> renderEngine)114 bool RSProcessor::Init(RSDisplayRenderNode& node, int32_t offsetX, int32_t offsetY, ScreenId mirroredId,
115                        std::shared_ptr<RSBaseRenderEngine> renderEngine)
116 {
117     offsetX_ = offsetX;
118     offsetY_ = offsetY;
119     mirroredId_ = mirroredId;
120     auto screenManager = CreateOrGetScreenManager();
121     if (screenManager == nullptr) {
122         RS_LOGE("RSPhysicalScreenProcessor::Init: ScreenManager is nullptr");
123         return false;
124     }
125     screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
126     screenInfo_.rotation = node.GetRotation();
127     auto mirrorNode = node.GetMirrorSource().lock();
128     CalculateScreenTransformMatrix(mirrorNode ? *mirrorNode : node);
129 
130     renderEngine_ = renderEngine;
131     if (renderEngine_ == nullptr) {
132         RS_LOGE("renderEngine is nullptr");
133         return false;
134     }
135 
136     if (mirroredId_ != INVALID_SCREEN_ID) {
137         auto mirroredScreenInfo = screenManager->QueryScreenInfo(mirroredId_);
138         CalculateMirrorAdaptiveCoefficient(
139             static_cast<float>(screenInfo_.width), static_cast<float>(screenInfo_.height),
140             static_cast<float>(mirroredScreenInfo.width), static_cast<float>(mirroredScreenInfo.height)
141         );
142     }
143 
144     // set default render frame config
145     renderFrameConfig_ = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo_);
146     return true;
147 }
148 
SetMirrorScreenSwap(const RSDisplayRenderNode & node)149 void RSProcessor::SetMirrorScreenSwap(const RSDisplayRenderNode& node)
150 {
151     auto mirroredNode = node.GetMirrorSource().lock();
152     if (mirroredNode == nullptr) {
153         RS_LOGE("RSProcessor::Init: Get mirroredNode failed");
154         return;
155     }
156     if (mirroredNode->GetRotation() == ScreenRotation::ROTATION_90 ||
157         mirroredNode->GetRotation() == ScreenRotation::ROTATION_270) {
158         std::swap(screenInfo_.width, screenInfo_.height);
159         std::swap(renderFrameConfig_.width, renderFrameConfig_.height);
160     }
161 }
162 
CalculateScreenTransformMatrix(const RSDisplayRenderNode & node)163 void RSProcessor::CalculateScreenTransformMatrix(const RSDisplayRenderNode& node)
164 {
165     auto boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
166     if (boundsGeoPtr != nullptr) {
167         boundsGeoPtr->UpdateByMatrixFromSelf();
168         screenTransformMatrix_ = boundsGeoPtr->GetMatrix();
169     }
170 }
171 
CalculateMirrorAdaptiveCoefficient(float curWidth,float curHeight,float mirroredWidth,float mirroredHeight)172 void RSProcessor::CalculateMirrorAdaptiveCoefficient(float curWidth, float curHeight,
173     float mirroredWidth, float mirroredHeight)
174 {
175     if (std::fabs(mirroredWidth) < 1e-6 || std::fabs(mirroredHeight) < 1e-6) {
176         RS_LOGE("RSSoftwareProcessor::Init mirroredScreen width or height is zero");
177         return;
178     }
179     mirrorAdaptiveCoefficient_ = std::min(curWidth / mirroredWidth, curHeight / mirroredHeight);
180 }
181 
MirrorScenePerf()182 void RSProcessor::MirrorScenePerf()
183 {
184     needDisableMultiLayersPerf_ = true;
185     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
186     auto currentTime = std::chrono::steady_clock::now();
187     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
188         count() > PERF_TIME_OUT;
189     if (isTimeOut) {
190         PerfRequest(PERF_LEVEL_3_REQUESTED_CODE, true);
191         lastRequestPerfTime = currentTime;
192     }
193 }
194 
MultiLayersPerf(size_t layerNum)195 void RSProcessor::MultiLayersPerf(size_t layerNum)
196 {
197     if (needDisableMultiLayersPerf_) {
198         auto& context = RSMainThread::Instance()->GetContext();
199         std::shared_ptr<RSBaseRenderNode> rootNode = context.GetGlobalRootRenderNode();
200         if (rootNode && rootNode->GetChildrenCount() <= 1) {
201             needDisableMultiLayersPerf_ = false;
202         } else {
203             return;
204         }
205     }
206 #ifdef FRAME_AWARE_TRACE
207     if (FrameAwareTraceBoost(layerNum)) {
208         return;
209     }
210 #endif
211     static uint32_t lastLayerLevel = 0;
212     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
213     auto curLayerLevel = layerNum / PERF_LEVEL_INTERVAL;
214     if (curLayerLevel == 0 && layerNum >= PERF_LAYER_START_NUM) {
215         curLayerLevel = 1;
216     }
217     auto currentTime = std::chrono::steady_clock::now();
218     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
219         count() > PERF_TIME_OUT;
220     if (curLayerLevel != lastLayerLevel || isTimeOut) {
221         if (!isTimeOut) {
222             RequestPerf(lastLayerLevel, false);
223         }
224         RequestPerf(curLayerLevel, true);
225         lastLayerLevel = curLayerLevel;
226         lastRequestPerfTime = currentTime;
227     }
228 }
229 
SetSecurityDisplay(bool isSecurityDisplay)230 void RSProcessor::SetSecurityDisplay(bool isSecurityDisplay)
231 {
232     isSecurityDisplay_ = isSecurityDisplay;
233 }
234 
SetDisplayHasSecSurface(bool displayHasSecSurface)235 void RSProcessor::SetDisplayHasSecSurface(bool displayHasSecSurface)
236 {
237     displayHasSecSurface_ = displayHasSecSurface;
238 }
239 
240 } // namespace Rosen
241 } // namespace OHOS
242