• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "pipeline/rs_draw_frame.h"
17 
18 #include <hitrace_meter.h>
19 #include <parameters.h>
20 
21 #include "rs_trace.h"
22 
23 #include "memory/rs_memory_manager.h"
24 #include "pipeline/rs_main_thread.h"
25 #include "pipeline/rs_render_node_gc.h"
26 #include "pipeline/rs_uifirst_manager.h"
27 #include "pipeline/rs_uni_render_thread.h"
28 #include "property/rs_filter_cache_manager.h"
29 #include "rs_frame_report.h"
30 
31 #include "rs_profiler.h"
32 
33 namespace OHOS {
34 namespace Rosen {
RSDrawFrame()35 RSDrawFrame::RSDrawFrame()
36     : unirenderInstance_(RSUniRenderThread::Instance()), rsParallelType_(RSSystemParameters::GetRsParallelType())
37 {}
38 
~RSDrawFrame()39 RSDrawFrame::~RSDrawFrame() noexcept {}
40 
SetRenderThreadParams(std::unique_ptr<RSRenderThreadParams> & stagingRenderThreadParams)41 void RSDrawFrame::SetRenderThreadParams(std::unique_ptr<RSRenderThreadParams>& stagingRenderThreadParams)
42 {
43     stagingRenderThreadParams_ = std::move(stagingRenderThreadParams);
44 }
45 
46 bool RSDrawFrame::debugTraceEnabled_ =
47     std::atoi((OHOS::system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
48 
RenderFrame()49 void RSDrawFrame::RenderFrame()
50 {
51     HitracePerfScoped perfTrace(RSDrawFrame::debugTraceEnabled_, HITRACE_TAG_GRAPHIC_AGP, "OnRenderFramePerfCount");
52     RS_TRACE_NAME_FMT("RenderFrame");
53     RSMainThread::GPUCompositonCacheGuard guard;
54     if (RsFrameReport::GetInstance().GetEnable()) {
55         RsFrameReport::GetInstance().RSRenderStart();
56     }
57     JankStatsRenderFrameStart();
58     unirenderInstance_.IncreaseFrameCount();
59     RSUifirstManager::Instance().ProcessSubDoneNode();
60     Sync();
61     const bool doJankStats = IsUniRenderAndOnVsync();
62     JankStatsRenderFrameAfterSync(doJankStats);
63     RSMainThread::Instance()->ProcessUiCaptureTasks();
64     RSUifirstManager::Instance().PostUifistSubTasks();
65     UnblockMainThread();
66     Render();
67     ReleaseSelfDrawingNodeBuffer();
68     NotifyClearGpuCache();
69     if (RsFrameReport::GetInstance().GetEnable()) {
70         RsFrameReport::GetInstance().RSRenderEnd();
71     }
72     RSMainThread::Instance()->CallbackDrawContextStatusToWMS(true);
73     RSRenderNodeGC::Instance().ReleaseDrawableMemory();
74     if (RSSystemProperties::GetPurgeBetweenFramesEnabled()) {
75         unirenderInstance_.PurgeCacheBetweenFrames();
76     }
77     unirenderInstance_.MemoryManagementBetweenFrames();
78     MemoryManager::MemoryOverCheck(unirenderInstance_.GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
79     JankStatsRenderFrameEnd(doJankStats);
80 }
81 
NotifyClearGpuCache()82 void RSDrawFrame::NotifyClearGpuCache()
83 {
84     if (RSFilterCacheManager::GetFilterInvalid()) {
85         unirenderInstance_.ClearMemoryCache(ClearMemoryMoment::FILTER_INVALID, true);
86         RSFilterCacheManager::SetFilterInvalid(false);
87     }
88 }
89 
ReleaseSelfDrawingNodeBuffer()90 void RSDrawFrame::ReleaseSelfDrawingNodeBuffer()
91 {
92     unirenderInstance_.ReleaseSelfDrawingNodeBuffer();
93 }
94 
PostAndWait()95 void RSDrawFrame::PostAndWait()
96 {
97     RS_TRACE_NAME_FMT("PostAndWait, parallel type %d", static_cast<int>(rsParallelType_));
98     uint32_t renderFrameNumber = RS_PROFILER_GET_FRAME_NUMBER();
99     switch (rsParallelType_) {
100         case RsParallelType::RS_PARALLEL_TYPE_SYNC: { // wait until render finish in render thread
101             unirenderInstance_.PostSyncTask([this, renderFrameNumber]() {
102                 unirenderInstance_.SetMainLooping(true);
103                 RS_PROFILER_ON_PARALLEL_RENDER_BEGIN();
104                 RenderFrame();
105                 unirenderInstance_.RunImageReleaseTask();
106                 RS_PROFILER_ON_PARALLEL_RENDER_END(renderFrameNumber);
107                 unirenderInstance_.SetMainLooping(false);
108             });
109             break;
110         }
111         case RsParallelType::RS_PARALLEL_TYPE_SINGLE_THREAD: { // render in main thread
112             RenderFrame();
113             unirenderInstance_.RunImageReleaseTask();
114             break;
115         }
116         case RsParallelType::RS_PARALLEL_TYPE_ASYNC: // wait until sync finish in render thread
117         default: {
118             std::unique_lock<std::mutex> frameLock(frameMutex_);
119             canUnblockMainThread = false;
120             unirenderInstance_.PostTask([this, renderFrameNumber]() {
121                 unirenderInstance_.SetMainLooping(true);
122                 RS_PROFILER_ON_PARALLEL_RENDER_BEGIN();
123                 RenderFrame();
124                 unirenderInstance_.RunImageReleaseTask();
125                 RS_PROFILER_ON_PARALLEL_RENDER_END(renderFrameNumber);
126                 unirenderInstance_.SetMainLooping(false);
127             });
128 
129             frameCV_.wait(frameLock, [this] { return canUnblockMainThread; });
130         }
131     }
132 }
133 
PostDirectCompositionJankStats(const JankDurationParams & rsParams)134 void RSDrawFrame::PostDirectCompositionJankStats(const JankDurationParams& rsParams)
135 {
136     RS_TRACE_NAME_FMT("PostDirectCompositionJankStats, parallel type %d", static_cast<int>(rsParallelType_));
137     switch (rsParallelType_) {
138         case RsParallelType::RS_PARALLEL_TYPE_SYNC: // wait until render finish in render thread
139         case RsParallelType::RS_PARALLEL_TYPE_SINGLE_THREAD: // render in main thread
140         case RsParallelType::RS_PARALLEL_TYPE_ASYNC: // wait until sync finish in render thread
141         default: {
142             bool isReportTaskDelayed = unirenderInstance_.IsMainLooping();
143             auto task = [rsParams, isReportTaskDelayed]() -> void {
144                 RSJankStats::GetInstance().HandleDirectComposition(rsParams, isReportTaskDelayed);
145             };
146             unirenderInstance_.PostTask(task);
147         }
148     }
149 }
150 
Sync()151 void RSDrawFrame::Sync()
152 {
153     RS_TRACE_NAME_FMT("Sync");
154     RSMainThread::Instance()->GetContext().GetGlobalRootRenderNode()->Sync();
155 
156     auto& pendingSyncNodes = RSMainThread::Instance()->GetContext().pendingSyncNodes_;
157     for (auto& [id, weakPtr] : pendingSyncNodes) {
158         if (auto node = weakPtr.lock()) {
159             if (!RSUifirstManager::Instance().CollectSkipSyncNode(node)) {
160                 node->Sync();
161             } else {
162                 node->SkipSync();
163             }
164         }
165     }
166     pendingSyncNodes.clear();
167 
168     unirenderInstance_.Sync(std::move(stagingRenderThreadParams_));
169 }
170 
UnblockMainThread()171 void RSDrawFrame::UnblockMainThread()
172 {
173     RS_TRACE_NAME_FMT("UnlockMainThread");
174     std::unique_lock<std::mutex> frameLock(frameMutex_);
175     if (!canUnblockMainThread) {
176         canUnblockMainThread = true;
177         frameCV_.notify_all();
178     }
179 }
180 
Render()181 void RSDrawFrame::Render()
182 {
183     RS_TRACE_NAME_FMT("Render vsyncId: %" PRIu64 "", unirenderInstance_.GetVsyncId());
184     unirenderInstance_.Render();
185 }
186 
JankStatsRenderFrameStart()187 void RSDrawFrame::JankStatsRenderFrameStart()
188 {
189     unirenderInstance_.SetSkipJankAnimatorFrame(false);
190 }
191 
IsUniRenderAndOnVsync() const192 bool RSDrawFrame::IsUniRenderAndOnVsync() const
193 {
194     const auto& renderThreadParams = unirenderInstance_.GetRSRenderThreadParams();
195     if (!renderThreadParams) {
196         return false;
197     }
198     return renderThreadParams->IsUniRenderAndOnVsync();
199 }
200 
JankStatsRenderFrameAfterSync(bool doJankStats)201 void RSDrawFrame::JankStatsRenderFrameAfterSync(bool doJankStats)
202 {
203     if (!doJankStats) {
204         return;
205     }
206     RSJankStats::GetInstance().SetStartTime();
207     RSJankStats::GetInstance().SetAccumulatedBufferCount(RSBaseRenderUtil::GetAccumulatedBufferCount());
208     unirenderInstance_.UpdateDisplayNodeScreenId();
209 }
210 
JankStatsRenderFrameEnd(bool doJankStats)211 void RSDrawFrame::JankStatsRenderFrameEnd(bool doJankStats)
212 {
213     if (!doJankStats) {
214         unirenderInstance_.SetDiscardJankFrames(false);
215         return;
216     }
217     const auto& renderThreadParams = unirenderInstance_.GetRSRenderThreadParams();
218     if (renderThreadParams == nullptr) {
219         return;
220     }
221     RSJankStats::GetInstance().SetOnVsyncStartTime(
222         renderThreadParams->GetOnVsyncStartTime(),
223         renderThreadParams->GetOnVsyncStartTimeSteady(),
224         renderThreadParams->GetOnVsyncStartTimeSteadyFloat());
225     RSJankStats::GetInstance().SetImplicitAnimationEnd(renderThreadParams->GetImplicitAnimationEnd());
226     RSJankStats::GetInstance().SetEndTime(
227         unirenderInstance_.GetSkipJankAnimatorFrame(),
228         unirenderInstance_.GetDiscardJankFrames() || renderThreadParams->GetDiscardJankFrames(),
229         unirenderInstance_.GetDynamicRefreshRate());
230     unirenderInstance_.SetDiscardJankFrames(false);
231 }
232 } // namespace Rosen
233 } // namespace OHOS
234