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: 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 mirroredScreenInfo_ = screenManager->QueryScreenInfo(mirroredId_);
185 mirroredScreenInfo_.rotation = mirrorNode->GetRotation();
186 CalculateMirrorAdaptiveMatrix();
187 }
188
189 // set default render frame config
190 renderFrameConfig_ = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo_);
191 return true;
192 }
193
SetMirrorScreenSwap(const RSDisplayRenderNode & node)194 void RSProcessor::SetMirrorScreenSwap(const RSDisplayRenderNode& node)
195 {
196 auto mirroredNode = node.GetMirrorSource().lock();
197 if (mirroredNode == nullptr) {
198 RS_LOGE("RSProcessor::Init: Get mirroredNode failed");
199 return;
200 }
201 if (mirroredNode->GetRotation() == ScreenRotation::ROTATION_90 ||
202 mirroredNode->GetRotation() == ScreenRotation::ROTATION_270) {
203 std::swap(screenInfo_.width, screenInfo_.height);
204 std::swap(renderFrameConfig_.width, renderFrameConfig_.height);
205 }
206 }
207
CalculateScreenTransformMatrix(const RSDisplayRenderNode & node)208 void RSProcessor::CalculateScreenTransformMatrix(const RSDisplayRenderNode& node)
209 {
210 auto& boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
211 if (boundsGeoPtr != nullptr) {
212 boundsGeoPtr->UpdateByMatrixFromSelf();
213 screenTransformMatrix_ = boundsGeoPtr->GetMatrix();
214 }
215 }
216
CalculateMirrorAdaptiveCoefficient(float curWidth,float curHeight,float mirroredWidth,float mirroredHeight)217 void RSProcessor::CalculateMirrorAdaptiveCoefficient(float curWidth, float curHeight,
218 float mirroredWidth, float mirroredHeight)
219 {
220 if (std::fabs(mirroredWidth) < 1e-6 || std::fabs(mirroredHeight) < 1e-6) {
221 RS_LOGE("RSSoftwareProcessor::Init mirroredScreen width or height is zero");
222 return;
223 }
224 mirrorAdaptiveCoefficient_ = std::min(curWidth / mirroredWidth, curHeight / mirroredHeight);
225 }
226
MirrorScenePerf()227 void RSProcessor::MirrorScenePerf()
228 {
229 needDisableMultiLayersPerf_ = true;
230 static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
231 auto currentTime = std::chrono::steady_clock::now();
232 bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
233 count() > PERF_TIME_OUT;
234 if (isTimeOut) {
235 PerfRequest(PERF_LEVEL_3_REQUESTED_CODE, true);
236 lastRequestPerfTime = currentTime;
237 }
238 }
239
MultiLayersPerf(size_t layerNum)240 void RSProcessor::MultiLayersPerf(size_t layerNum)
241 {
242 if (needDisableMultiLayersPerf_) {
243 auto& context = RSMainThread::Instance()->GetContext();
244 std::shared_ptr<RSBaseRenderNode> rootNode = context.GetGlobalRootRenderNode();
245 if (rootNode && rootNode->GetChildrenCount() <= 1) {
246 needDisableMultiLayersPerf_ = false;
247 } else {
248 return;
249 }
250 }
251 #ifdef FRAME_AWARE_TRACE
252 if (FrameAwareTraceBoost(layerNum)) {
253 return;
254 }
255 #endif
256 static uint32_t lastLayerLevel = 0;
257 static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
258 auto curLayerLevel = layerNum / PERF_LEVEL_INTERVAL;
259 if (curLayerLevel == 0 && layerNum >= PERF_LAYER_START_NUM) {
260 curLayerLevel = 1;
261 }
262 auto currentTime = std::chrono::steady_clock::now();
263 bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
264 count() > PERF_TIME_OUT;
265 if (curLayerLevel != lastLayerLevel || isTimeOut) {
266 if (!isTimeOut) {
267 RequestPerf(lastLayerLevel, false);
268 }
269 RequestPerf(curLayerLevel, true);
270 lastLayerLevel = curLayerLevel;
271 lastRequestPerfTime = currentTime;
272 }
273 }
274
SetSecurityDisplay(bool isSecurityDisplay)275 void RSProcessor::SetSecurityDisplay(bool isSecurityDisplay)
276 {
277 isSecurityDisplay_ = isSecurityDisplay;
278 }
279
SetDisplayHasSecSurface(bool displayHasSecSurface)280 void RSProcessor::SetDisplayHasSecSurface(bool displayHasSecSurface)
281 {
282 displayHasSecSurface_ = displayHasSecSurface;
283 }
284
CalculateMirrorAdaptiveMatrix()285 void RSProcessor::CalculateMirrorAdaptiveMatrix()
286 {
287 CalculateMirrorAdaptiveCoefficient(static_cast<float>(screenInfo_.GetRotatedWidth()),
288 static_cast<float>(screenInfo_.GetRotatedHeight()), static_cast<float>(mirroredScreenInfo_.GetRotatedWidth()),
289 static_cast<float>(mirroredScreenInfo_.GetRotatedHeight()));
290
291 float rotation = 0.0f;
292 float offsetX = 0.0f;
293 float offsetY = 0.0f;
294
295 switch (screenInfo_.rotation) {
296 case ScreenRotation::ROTATION_90:
297 rotation = -90.0f;
298 offsetX = screenInfo_.GetRotatedWidth() * -1.0f;
299 break;
300 case ScreenRotation::ROTATION_180:
301 rotation = -180.0f;
302 offsetX = screenInfo_.GetRotatedWidth() * -1.0f;
303 offsetY = screenInfo_.GetRotatedHeight() * -1.0f;
304 break;
305 case ScreenRotation::ROTATION_270:
306 rotation = -270.0f;
307 offsetY = screenInfo_.GetRotatedHeight() * -1.0f;
308 break;
309 default:
310 break;
311 }
312
313 // align center
314 offsetX +=
315 (screenInfo_.GetRotatedWidth() - mirroredScreenInfo_.GetRotatedWidth() * mirrorAdaptiveCoefficient_) / 2.0f;
316 offsetY +=
317 (screenInfo_.GetRotatedHeight() - mirroredScreenInfo_.GetRotatedHeight() * mirrorAdaptiveCoefficient_) /
318 2.0f;
319
320 mirrorAdaptiveMatrix_.PreRotate(rotation);
321 mirrorAdaptiveMatrix_.PreTranslate(offsetX, offsetY);
322 mirrorAdaptiveMatrix_.PreScale(mirrorAdaptiveCoefficient_, mirrorAdaptiveCoefficient_);
323 }
324
325 } // namespace Rosen
326 } // namespace OHOS
327