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