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 #include "socperf_client.h"
23 #ifdef FRAME_AWARE_TRACE
24 #include "render_frame_trace.h"
25
26 using namespace FRAME_TRACE;
27 #endif
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 constexpr uint32_t PERF_LEVEL_0 = 0;
33 constexpr uint32_t PERF_LEVEL_1 = 1;
34 constexpr uint32_t PERF_LEVEL_2 = 2;
35 constexpr int32_t PERF_LEVEL_1_REQUESTED_CODE = 10013;
36 constexpr int32_t PERF_LEVEL_2_REQUESTED_CODE = 10014;
37 constexpr int32_t PERF_LEVEL_3_REQUESTED_CODE = 10015;
38 constexpr int64_t PERF_TIME_OUT = 950;
39 constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
40 constexpr uint32_t PERF_LAYER_START_NUM = 7;
41 #ifdef FRAME_AWARE_TRACE
42 constexpr uint32_t FRAME_TRACE_LAYER_NUM_1 = 11;
43 constexpr uint32_t FRAME_TRACE_LAYER_NUM_2 = 13;
44 constexpr int32_t FRAME_TRACE_PERF_REQUESTED_CODE = 10024;
45 #endif
46 }
47
48 #ifdef FRAME_AWARE_TRACE
FrameAwareTraceBoost(size_t layerNum)49 bool RSProcessor::FrameAwareTraceBoost(size_t layerNum)
50 {
51 RenderFrameTrace& ft = RenderFrameTrace::GetInstance();
52 if (layerNum != FRAME_TRACE_LAYER_NUM_1 && layerNum != FRAME_TRACE_LAYER_NUM_2) {
53 if (ft.RenderFrameTraceIsOpen()) {
54 ft.RenderFrameTraceClose();
55 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(FRAME_TRACE_PERF_REQUESTED_CODE, false, "");
56 RS_LOGI("RsDebug RSProcessor::Perf: FrameTrace 0");
57 }
58 return false;
59 }
60
61 static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
62 auto currentTime = std::chrono::steady_clock::now();
63 bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
64 count() > PERF_TIME_OUT;
65 if (isTimeOut || !ft.RenderFrameTraceIsOpen()) {
66 if (!ft.RenderFrameTraceOpen()) {
67 return false;
68 }
69 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(FRAME_TRACE_PERF_REQUESTED_CODE, true, "");
70 RS_LOGI("RsDebug RSProcessor::Perf: FrameTrace 1");
71 lastRequestPerfTime = currentTime;
72 }
73 return true;
74 }
75 #endif
76
RequestPerf(uint32_t layerLevel,bool onOffTag)77 void RSProcessor::RequestPerf(uint32_t layerLevel, bool onOffTag)
78 {
79 switch (layerLevel) {
80 case PERF_LEVEL_0: {
81 // do nothing
82 RS_LOGI("RsDebug RSProcessor::Perf: do nothing");
83 break;
84 }
85 case PERF_LEVEL_1: {
86 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_LEVEL_1_REQUESTED_CODE, onOffTag, "");
87 RS_LOGI("RsDebug RSProcessor::Perf: level1 %d", onOffTag);
88 break;
89 }
90 case PERF_LEVEL_2: {
91 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_LEVEL_2_REQUESTED_CODE, onOffTag, "");
92 RS_LOGI("RsDebug RSProcessor::Perf: level2 %d", onOffTag);
93 break;
94 }
95 default: {
96 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_LEVEL_3_REQUESTED_CODE, onOffTag, "");
97 RS_LOGI("RsDebug RSProcessor::Perf: level3 %d", onOffTag);
98 break;
99 }
100 }
101 }
102
Init(RSDisplayRenderNode & node,int32_t offsetX,int32_t offsetY,ScreenId mirroredId)103 bool RSProcessor::Init(RSDisplayRenderNode& node, int32_t offsetX, int32_t offsetY, ScreenId mirroredId)
104 {
105 offsetX_ = offsetX;
106 offsetY_ = offsetY;
107 mirroredId_ = mirroredId;
108 auto screenManager = CreateOrGetScreenManager();
109 if (screenManager == nullptr) {
110 RS_LOGE("RSPhysicalScreenProcessor::Init: ScreenManager is nullptr");
111 return false;
112 }
113 screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
114 screenInfo_.rotation = node.GetRotation();
115 CalculateScreenTransformMatrix(node);
116
117 auto mainThread = RSMainThread::Instance();
118 if (mainThread != nullptr) {
119 renderEngine_ = mainThread->GetRenderEngine();
120 }
121 if (renderEngine_ == nullptr) {
122 return false;
123 }
124
125 if (mirroredId_ != INVALID_SCREEN_ID) {
126 auto mirroredScreenInfo = screenManager->QueryScreenInfo(mirroredId_);
127 CalculateMirrorAdaptiveCoefficient(
128 static_cast<float>(screenInfo_.width), static_cast<float>(screenInfo_.height),
129 static_cast<float>(mirroredScreenInfo.width), static_cast<float>(mirroredScreenInfo.height)
130 );
131 }
132
133 // set default render frame config
134 renderFrameConfig_ = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo_);
135 return true;
136 }
137
SetMirrorScreenSwap(const RSDisplayRenderNode & node)138 void RSProcessor::SetMirrorScreenSwap(const RSDisplayRenderNode& node)
139 {
140 auto mirroredNode = node.GetMirrorSource().lock();
141 if (mirroredNode == nullptr) {
142 RS_LOGE("RSProcessor::Init: Get mirroredNode failed");
143 }
144 if (mirroredNode->GetRotation() == ScreenRotation::ROTATION_90 ||
145 mirroredNode->GetRotation() == ScreenRotation::ROTATION_270) {
146 std::swap(screenInfo_.width, screenInfo_.height);
147 std::swap(renderFrameConfig_.width, renderFrameConfig_.height);
148 }
149 }
150
CalculateScreenTransformMatrix(const RSDisplayRenderNode & node)151 void RSProcessor::CalculateScreenTransformMatrix(const RSDisplayRenderNode& node)
152 {
153 auto boundsGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
154 if (boundsGeoPtr != nullptr) {
155 boundsGeoPtr->UpdateByMatrixFromSelf();
156 screenTransformMatrix_ = boundsGeoPtr->GetMatrix();
157 }
158 }
159
CalculateMirrorAdaptiveCoefficient(float curWidth,float curHeight,float mirroredWidth,float mirroredHeight)160 void RSProcessor::CalculateMirrorAdaptiveCoefficient(float curWidth, float curHeight,
161 float mirroredWidth, float mirroredHeight)
162 {
163 if (std::fabs(mirroredWidth) < 1e-6 || std::fabs(mirroredHeight) < 1e-6) {
164 RS_LOGE("RSSoftwareProcessor::Init mirroredScreen width or height is zero");
165 return;
166 }
167 mirrorAdaptiveCoefficient_ = std::min(curWidth / mirroredWidth, curHeight / mirroredHeight);
168 }
169
MultiLayersPerf(size_t layerNum)170 void RSProcessor::MultiLayersPerf(size_t layerNum)
171 {
172 #ifdef FRAME_AWARE_TRACE
173 if (FrameAwareTraceBoost(layerNum)) {
174 return;
175 }
176 #endif
177 static uint32_t lastLayerLevel = 0;
178 static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
179 auto curLayerLevel = layerNum / PERF_LEVEL_INTERVAL;
180 if (curLayerLevel == 0 && layerNum >= PERF_LAYER_START_NUM) {
181 curLayerLevel = 1;
182 }
183 auto currentTime = std::chrono::steady_clock::now();
184 bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
185 count() > PERF_TIME_OUT;
186 if (curLayerLevel != lastLayerLevel || isTimeOut) {
187 if (!isTimeOut) {
188 RequestPerf(lastLayerLevel, false);
189 }
190 RequestPerf(curLayerLevel, true);
191 lastLayerLevel = curLayerLevel;
192 lastRequestPerfTime = currentTime;
193 }
194 }
195 } // namespace Rosen
196 } // namespace OHOS
197