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