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