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