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