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