• 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 "rs_parallel_render_manager.h"
17 #include <cstddef>
18 #include <cstdint>
19 #include <memory>
20 #include <mutex>
21 
22 #include "EGL/egl.h"
23 #include "rs_render_task.h"
24 #include "pipeline/rs_base_render_engine.h"
25 #include "pipeline/rs_main_thread.h"
26 #include "pipeline/rs_uni_render_engine.h"
27 #include "pipeline/rs_uni_render_listener.h"
28 #include "pipeline/rs_uni_render_visitor.h"
29 #include "rs_parallel_render_ext.h"
30 #include "rs_trace.h"
31 
32 
33 namespace OHOS {
34 namespace Rosen {
35 
36 static constexpr uint32_t PARALLEL_THREAD_NUM = 3;
37 static constexpr int32_t MAX_CALC_COST_COUNT = 20;
38 
Instance()39 RSParallelRenderManager* RSParallelRenderManager::Instance()
40 {
41     static RSParallelRenderManager instance;
42     return &instance;
43 }
44 
RSParallelRenderManager()45 RSParallelRenderManager::RSParallelRenderManager()
46     : taskType_(TaskType::PROCESS_TASK),
47       parallelHardwareComposer_(std::make_unique<RSParallelHardwareComposer>())
48 {
49     if (parallelHardwareComposer_) {
50         InitAppWindowNodeMap();
51         parallelHardwareComposer_->Init(PARALLEL_THREAD_NUM);
52     }
53     if (ParallelRenderExtEnabled()) {
54         startTime_.assign(PARALLEL_THREAD_NUM, {});
55         stopTime_.assign(PARALLEL_THREAD_NUM, {});
56     }
57     readyBufferNum_ = 0;
58 #ifdef RS_ENABLE_VK
59     parallelDisplayNodes_.assign(PARALLEL_THREAD_NUM, nullptr);
60     backParallelDisplayNodes_.assign(PARALLEL_THREAD_NUM, nullptr);
61 #endif
62 }
63 
InitAppWindowNodeMap()64 void RSParallelRenderManager::InitAppWindowNodeMap()
65 {
66     auto appWindowNode = std::vector<std::shared_ptr<RSSurfaceRenderNode>>();
67     for (uint32_t i = 0; i < PARALLEL_THREAD_NUM; i++) {
68         appWindowNodesMap_[i] = appWindowNode;
69     }
70 }
71 
SetParallelMode(bool parallelMode)72 void RSParallelRenderManager::SetParallelMode(bool parallelMode)
73 {
74     parallelMode_ = parallelMode;
75     TryEnableParallelRendering();
76 }
77 
78 // You should always use GetParallelModeSafe() instead of GetParallelMode()
79 // except initialize variable 'isParallel' in 'rs_uni_render_visitor.cpp'
GetParallelModeSafe() const80 bool RSParallelRenderManager::GetParallelModeSafe() const
81 {
82     return GetParallelRenderingStatus() == ParallelStatus::ON;
83 }
84 
GetParallelMode() const85 bool RSParallelRenderManager::GetParallelMode() const
86 {
87     ParallelStatus status = GetParallelRenderingStatus();
88     return (status == ParallelStatus::ON) || (status == ParallelStatus::FIRSTFLUSH);
89 }
90 
91 #ifdef NEW_RENDER_CONTEXT
StartSubRenderThread(uint32_t threadNum,std::shared_ptr<RenderContextBase> context,std::shared_ptr<DrawingContext> drawingContext)92 void RSParallelRenderManager::StartSubRenderThread(uint32_t threadNum, std::shared_ptr<RenderContextBase> context,
93     std::shared_ptr<DrawingContext> drawingContext)
94 #else
95 void RSParallelRenderManager::StartSubRenderThread(uint32_t threadNum, RenderContext *context)
96 #endif
97 {
98     if (GetParallelRenderingStatus() == ParallelStatus::OFF) {
99         expectedSubThreadNum_ = threadNum;
100         flipCoin_ = std::vector<uint8_t>(expectedSubThreadNum_, 0);
101         firstFlush_ = true;
102         renderContext_ = context;
103 #ifdef NEW_RENDER_CONTEXT
104         drawingContext_ = drawingContext;
105 #endif
106 #ifdef RS_ENABLE_GL
107         if (context) {
108 #endif
109             for (uint32_t i = 0; i < threadNum; ++i) {
110                 auto curThread = std::make_unique<RSParallelSubThread>(context, renderType_, i);
111                 curThread->StartSubThread();
112                 threadList_.push_back(std::move(curThread));
113             }
114 #ifdef RS_ENABLE_GL
115         }
116 #endif
117         processTaskManager_.Initialize(threadNum);
118         prepareTaskManager_.Initialize(threadNum);
119         calcCostTaskManager_.Initialize(threadNum);
120         compositionTaskManager_.Initialize(threadNum);
121     }
122 }
123 
EndSubRenderThread()124 void RSParallelRenderManager::EndSubRenderThread()
125 {
126     if (GetParallelRenderingStatus() == ParallelStatus::ON) {
127         for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
128             flipCoin_[i] = 1;
129         }
130         readySubThreadNum_ = expectedSubThreadNum_ = 0;
131         cvParallelRender_.notify_all();
132         packVisitor_ = nullptr;
133         packVisitorPrepare_ = nullptr;
134         calcCostVisitor_ = nullptr;
135         for (auto &thread : threadList_) {
136             thread->WaitSubMainThreadEnd();
137         }
138         std::vector<std::unique_ptr<RSParallelSubThread>>().swap(threadList_);
139         uniVisitor_ = nullptr;
140     }
141 }
142 
ReadySubThreadNumIncrement()143 void RSParallelRenderManager::ReadySubThreadNumIncrement()
144 {
145     ++readySubThreadNum_;
146 }
147 
GetParallelRenderingStatus() const148 ParallelStatus RSParallelRenderManager::GetParallelRenderingStatus() const
149 {
150     if (expectedSubThreadNum_ == 0) {
151         return ParallelStatus::OFF;
152     } else if (expectedSubThreadNum_ == readySubThreadNum_) {
153         return ParallelStatus::ON;
154     } else if (firstFlush_) {
155         return ParallelStatus::FIRSTFLUSH;
156     } else {
157         return ParallelStatus::WAITFIRSTFLUSH;
158     }
159 }
160 
CopyVisitorAndPackTask(RSUniRenderVisitor & visitor,RSDisplayRenderNode & node)161 void RSParallelRenderManager::CopyVisitorAndPackTask(RSUniRenderVisitor &visitor, RSDisplayRenderNode &node)
162 {
163     packVisitor_ = std::make_shared<RSParallelPackVisitor>(visitor);
164     displayNode_ = node.shared_from_this();
165     processTaskManager_.Reset();
166     processTaskManager_.LoadParallelPolicy(parallelPolicy_);
167     packVisitor_->ProcessDisplayRenderNode(node);
168     uniVisitor_ = &visitor;
169     taskType_ = TaskType::PROCESS_TASK;
170 }
171 
CopyPrepareVisitorAndPackTask(RSUniRenderVisitor & visitor,RSDisplayRenderNode & node)172 void RSParallelRenderManager::CopyPrepareVisitorAndPackTask(RSUniRenderVisitor &visitor, RSDisplayRenderNode &node)
173 {
174     packVisitorPrepare_ = std::make_shared<RSParallelPackVisitor>();
175     uniVisitor_ = &visitor;
176     displayNode_ = node.shared_from_this();
177     prepareTaskManager_.Reset();
178     packVisitorPrepare_->PrepareDisplayRenderNode(node);
179     taskType_ = TaskType::PREPARE_TASK;
180 }
181 
CopyCalcCostVisitorAndPackTask(RSUniRenderVisitor & visitor,RSDisplayRenderNode & node,bool isNeedCalc,bool doAnimate,bool isOpDropped)182 void RSParallelRenderManager::CopyCalcCostVisitorAndPackTask(RSUniRenderVisitor &visitor,
183     RSDisplayRenderNode &node, bool isNeedCalc, bool doAnimate, bool isOpDropped)
184 {
185     calcCostTaskManager_.Reset();
186     if (isNeedCalc) {
187         calcCostCount_ = MAX_CALC_COST_COUNT;
188     }
189     if (calcCostCount_ > 0) {
190         calcCostCount_--;
191     }
192     if (IsNeedCalcCost()) {
193         calcCostVisitor_ =  std::make_shared<RSParallelPackVisitor>(visitor);
194         uniVisitor_ = &visitor;
195         displayNode_ = node.shared_from_this();
196         calcCostVisitor_->CalcDisplayRenderNodeCost(node);
197         taskType_ = TaskType::CALC_COST_TASK;
198         GetCostFactor();
199         doAnimate_ = doAnimate;
200         isOpDropped_ = isOpDropped;
201         isSecurityDisplay_ = node.GetSecurityDisplay();
202     }
203 }
204 
IsNeedCalcCost() const205 bool RSParallelRenderManager::IsNeedCalcCost() const
206 {
207     return calcCostCount_ > 0;
208 }
209 
GetTaskType() const210 TaskType RSParallelRenderManager::GetTaskType() const
211 {
212     return taskType_;
213 }
214 
PackRenderTask(RSSurfaceRenderNode & node,TaskType type)215 void RSParallelRenderManager::PackRenderTask(RSSurfaceRenderNode &node, TaskType type)
216 {
217     switch (type) {
218         case TaskType::PREPARE_TASK:
219             prepareTaskManager_.PushRenderTask(
220                 std::make_unique<RSRenderTask>(node, RSRenderTask::RenderNodeStage::PREPARE));
221             break;
222         case TaskType::PROCESS_TASK:
223             processTaskManager_.PushRenderTask(
224                 std::make_unique<RSRenderTask>(node, RSRenderTask::RenderNodeStage::PROCESS));
225             break;
226         case TaskType::CALC_COST_TASK:
227             calcCostTaskManager_.PushRenderTask(
228                 std::make_unique<RSRenderTask>(node, RSRenderTask::RenderNodeStage::CALC_COST));
229             break;
230         default:
231             break;
232     }
233 }
234 
PackParallelCompositionTask(std::shared_ptr<RSNodeVisitor> visitor,const std::shared_ptr<RSBaseRenderNode> node)235 void RSParallelRenderManager::PackParallelCompositionTask(std::shared_ptr<RSNodeVisitor> visitor,
236                                                           const std::shared_ptr<RSBaseRenderNode> node)
237 {
238     uniParallelCompositionVisitor_ = std::static_pointer_cast<RSUniRenderVisitor>(visitor);
239     baseNode_ = node;
240     compositionTaskManager_.Reset();
241     auto children = node->GetSortedChildren();
242     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
243         std::shared_ptr<RSDisplayRenderNode> displayNode =
244             RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(*iter);
245         if (*iter == *children.begin()) {
246             mainDisplayNode_ = displayNode;
247             break;
248         }
249         compositionTaskManager_.PushCompositionTask(std::make_unique<RSCompositionTask>(displayNode));
250     }
251     taskType_ = TaskType::COMPOSITION_TASK;
252 }
253 
LoadBalanceAndNotify(TaskType type)254 void RSParallelRenderManager::LoadBalanceAndNotify(TaskType type)
255 {
256     InitAppWindowNodeMap();
257     switch (type) {
258         case TaskType::PREPARE_TASK:
259             prepareTaskManager_.LBCalcAndSubmitSuperTask(displayNode_);
260             break;
261         case TaskType::PROCESS_TASK:
262             processTaskManager_.LBCalcAndSubmitSuperTask(displayNode_);
263             break;
264         case TaskType::CALC_COST_TASK:
265             calcCostTaskManager_.LBCalcAndSubmitSuperTask(displayNode_);
266             break;
267         case TaskType::COMPOSITION_TASK:
268             compositionTaskManager_.LBCalcAndSubmitCompositionTask(baseNode_);
269             break;
270         default:
271             break;
272     }
273     for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
274         flipCoin_[i] = 1;
275     }
276     cvParallelRender_.notify_all();
277     if (type == TaskType::COMPOSITION_TASK) {
278         auto mainThread = RSMainThread::Instance();
279         if (mainThread == nullptr) {
280             RS_LOGE("RS main thread is nullptr.");
281             return;
282         }
283         std::shared_ptr<RSBaseRenderEngine> renderEngine = mainThread->GetRenderEngine();
284         uniParallelCompositionVisitor_->SetProcessorRenderEngine(renderEngine);
285         mainDisplayNode_->Process(uniParallelCompositionVisitor_);
286         uniParallelCompositionVisitor_ = nullptr;
287     }
288 }
289 
WaitPrepareEnd(RSUniRenderVisitor & visitor)290 void RSParallelRenderManager::WaitPrepareEnd(RSUniRenderVisitor &visitor)
291 {
292     for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
293         WaitSubMainThread(i);
294         visitor.CopyForParallelPrepare(threadList_[i]->GetUniVisitor());
295     }
296 }
297 
WaitProcessEnd()298 void RSParallelRenderManager::WaitProcessEnd()
299 {
300     for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
301         WaitSubMainThread(i);
302     }
303 }
304 
WaitCompositionEnd()305 void RSParallelRenderManager::WaitCompositionEnd()
306 {
307     for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
308         WaitSubMainThread(i);
309     }
310 }
311 
DrawImageMergeFunc(RSPaintFilterCanvas & canvas)312 void RSParallelRenderManager::DrawImageMergeFunc(RSPaintFilterCanvas& canvas)
313 {
314     for (unsigned int i = 0; i < expectedSubThreadNum_; ++i) {
315         RS_TRACE_BEGIN("Wait Render finish");
316         WaitSubMainThread(i);
317         RS_TRACE_END();
318         if (i < processTaskManager_.GetTaskNum()) {
319             RS_TRACE_BEGIN("Wait Fence Ready");
320             threadList_[i]->WaitReleaseFence();
321             RS_TRACE_END();
322             auto texture = threadList_[i]->GetTexture();
323             if (texture == nullptr) {
324                 RS_LOGE("Texture of subThread(%d) is nullptr", i);
325                 continue;
326             }
327 #ifndef USE_ROSEN_DRAWING
328 #ifdef NEW_SKIA
329             if (renderContext_ == nullptr) {
330                 RS_LOGE("RS main thread render context is nullptr");
331                 continue;
332             }
333 #ifdef NEW_RENDER_CONTEXT
334             auto mainGrContext = drawingContext_->GetDrawingContext();
335 #else
336             auto mainGrContext = renderContext_->GetGrContext();
337 #endif
338             if (mainGrContext == nullptr) {
339                 RS_LOGE("RS main thread GrDirectContext is nullptr");
340                 continue;
341             }
342             auto sharedBackendTexture = texture->getBackendTexture(false);
343             if (!sharedBackendTexture.isValid()) {
344                 RS_LOGE("Texture of subThread(%d) does not has GPU backend", i);
345                 continue;
346             }
347             auto sharedTexture = SkImage::MakeFromTexture(mainGrContext, sharedBackendTexture,
348                 kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
349             if (sharedTexture == nullptr) {
350                 RS_LOGE("SharedTexture of subThread(%d) is nullptr", i);
351             }
352             canvas.drawImage(sharedTexture, 0, 0);
353 #else
354             canvas.drawImage(texture, 0, 0);
355 #endif
356 #else
357             canvas.DrawImage(*texture, 0, 0, Drawing::SamplingOptions());
358 #endif
359             // For any one subMainThread' sksurface, we just clear transparent color of self drawing
360             // surface drawed in larger skSurface, such as skSurface 0 should clear self drawing surface
361             // areas drawed in skSurface 1.
362             auto clearTransparentColorSurfaceIndex = i + 1;
363             ClearSelfDrawingSurface(canvas, clearTransparentColorSurfaceIndex);
364 #ifndef USE_ROSEN_DRAWING
365 #ifdef NEW_SKIA
366             sharedTexture.reset();
367             sharedTexture = nullptr;
368             texture.reset();
369             texture = nullptr;
370 #endif
371 #endif
372         }
373     }
374 }
375 
FlushOneBufferFunc()376 void RSParallelRenderManager::FlushOneBufferFunc()
377 {
378 #ifdef NEW_RENDER_CONTEXT
379     renderContext_->MakeCurrent(nullptr, EGL_NO_CONTEXT);
380 #else
381     renderContext_->ShareMakeCurrent(EGL_NO_CONTEXT);
382 #endif
383     for (unsigned int i = 0; i < threadList_.size(); ++i) {
384         if (threadList_[i] == nullptr) {
385             return;
386         }
387 #ifdef NEW_RENDER_CONTEXT
388         renderContext_->MakeCurrent(nullptr, threadList_[i]->GetSharedContext());
389 #else
390         renderContext_->ShareMakeCurrent(threadList_[i]->GetSharedContext());
391 #endif
392         RS_TRACE_BEGIN("Start Flush");
393 #ifndef USE_ROSEN_DRAWING
394         auto skSurface = threadList_[i]->GetSkSurface();
395         if (skSurface) {
396             skSurface->flush();
397         } else {
398             RS_LOGE("skSurface is nullptr, thread index:%d", i);
399         }
400 #else
401         auto drSurface = threadList_[i]->GetDrawingSurface();
402         if (drSurface) {
403             auto canvas = drSurface->GetCanvas();
404             canvas->Flush();
405         } else {
406             RS_LOGE("skSurface is nullptr, thread index:%d", i);
407         }
408 #endif
409         RS_TRACE_END();
410 #ifdef NEW_RENDER_CONTEXT
411         renderContext_->MakeCurrent(nullptr, EGL_NO_CONTEXT);
412 #else
413         renderContext_->ShareMakeCurrent(EGL_NO_CONTEXT);
414 #endif
415     }
416 #ifdef NEW_RENDER_CONTEXT
417     renderContext_->MakeCurrent();
418 #else
419     renderContext_->MakeSelfCurrent();
420 #endif
421 }
422 
MergeRenderResult(RSPaintFilterCanvas & canvas)423 void RSParallelRenderManager::MergeRenderResult(RSPaintFilterCanvas& canvas)
424 {
425     if (GetParallelRenderingStatus() == ParallelStatus::FIRSTFLUSH) {
426         firstFlush_ = false;
427         for (unsigned int i = 0; i < expectedSubThreadNum_; ++i) {
428             WaitSubMainThread(i);
429         }
430         return;
431     }
432     if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
433         DrawImageMergeFunc(canvas);
434     } else {
435         FlushOneBufferFunc();
436     }
437     if (parallelHardwareComposer_) {
438         parallelHardwareComposer_->Init(PARALLEL_THREAD_NUM);
439     }
440 }
441 
SetFrameSize(int width,int height)442 void RSParallelRenderManager::SetFrameSize(int width, int height)
443 {
444     width_ = width;
445     height_ = height;
446 }
447 
GetFrameSize(int & width,int & height) const448 void RSParallelRenderManager::GetFrameSize(int &width, int &height) const
449 {
450     width = width_;
451     height = height_;
452 }
453 
SubmitSuperTask(uint32_t taskIndex,std::unique_ptr<RSSuperRenderTask> superRenderTask)454 void RSParallelRenderManager::SubmitSuperTask(uint32_t taskIndex, std::unique_ptr<RSSuperRenderTask> superRenderTask)
455 {
456     if (taskIndex >= threadList_.size()) {
457         RS_LOGE("taskIndex geq thread num");
458         return;
459     }
460     threadList_[taskIndex]->SetSuperTask(std::move(superRenderTask));
461 }
462 
SubmitCompositionTask(uint32_t taskIndex,std::unique_ptr<RSCompositionTask> compositionTask)463 void RSParallelRenderManager::SubmitCompositionTask(uint32_t taskIndex,
464                                                     std::unique_ptr<RSCompositionTask> compositionTask)
465 {
466     if (taskIndex >= threadList_.size()) {
467         RS_LOGE("taskIndex geq thread num");
468         return;
469     }
470 
471     if (threadList_[taskIndex] != nullptr) {
472         threadList_[taskIndex]->SetCompositionTask(std::move(compositionTask));
473     }
474 }
475 
476 // called by submain threads
SubMainThreadNotify(int threadIndex)477 void RSParallelRenderManager::SubMainThreadNotify(int threadIndex)
478 {
479     flipCoin_[threadIndex] = 0;
480     std::unique_lock<std::mutex> lock(cvParallelRenderMutex_);
481     for (unsigned int i = 0; i < expectedSubThreadNum_; ++i) {
482         if (flipCoin_[i] != 0) {
483             return;
484         }
485     }
486     cvParallelRender_.notify_all();
487 }
488 
489 // called by main thread
WaitSubMainThread(uint32_t threadIndex)490 void RSParallelRenderManager::WaitSubMainThread(uint32_t threadIndex)
491 {
492     std::unique_lock<std::mutex> lock(parallelRenderMutex_);
493     cvParallelRender_.wait(lock, [&]() {
494         return !flipCoin_[threadIndex];
495     });
496 }
497 
498 // called by submain threads
SubMainThreadWait(uint32_t threadIndex)499 void RSParallelRenderManager::SubMainThreadWait(uint32_t threadIndex)
500 {
501     std::unique_lock<std::mutex> lock(parallelRenderMutex_);
502     cvParallelRender_.wait(lock, [&]() {
503         return flipCoin_[threadIndex];
504     });
505 }
506 
StartTiming(uint32_t subMainThreadIdx)507 void RSParallelRenderManager::StartTiming(uint32_t subMainThreadIdx)
508 {
509     if (ParallelRenderExtEnabled()) {
510         clock_gettime(CLOCK_THREAD_CPUTIME_ID, &startTime_[subMainThreadIdx]);
511     }
512 }
513 
StopTimingAndSetRenderTaskCost(uint32_t subMainThreadIdx,uint64_t loadId,TaskType type)514 void RSParallelRenderManager::StopTimingAndSetRenderTaskCost(
515     uint32_t subMainThreadIdx, uint64_t loadId, TaskType type)
516 {
517     if (!ParallelRenderExtEnabled()) {
518         return;
519     }
520     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stopTime_[subMainThreadIdx]);
521     float cost =
522         (stopTime_[subMainThreadIdx].tv_sec * 1000.0f + stopTime_[subMainThreadIdx].tv_nsec * 1e-6) -
523         (startTime_[subMainThreadIdx].tv_sec * 1000.0f + startTime_[subMainThreadIdx].tv_nsec * 1e-6);
524     switch (type) {
525         case TaskType::PREPARE_TASK:
526             prepareTaskManager_.SetSubThreadRenderTaskLoad(subMainThreadIdx, loadId, cost);
527             break;
528         case TaskType::PROCESS_TASK:
529             processTaskManager_.SetSubThreadRenderTaskLoad(subMainThreadIdx, loadId, cost);
530             break;
531         case TaskType::CALC_COST_TASK:
532             calcCostTaskManager_.SetSubThreadRenderTaskLoad(subMainThreadIdx, loadId, cost);
533             break;
534         default:
535             break;
536     }
537 }
538 
ParallelRenderExtEnabled()539 bool RSParallelRenderManager::ParallelRenderExtEnabled()
540 {
541     return processTaskManager_.GetParallelRenderExtEnable();
542 }
543 
TryEnableParallelRendering()544 void RSParallelRenderManager::TryEnableParallelRendering()
545 {
546     auto renderEngine = RSMainThread::Instance()->GetRenderEngine();
547     if (!renderEngine) {
548         renderEngine = std::make_shared<RSUniRenderEngine>();
549         renderEngine->Init();
550     }
551     if (parallelMode_) {
552 #ifdef NEW_RENDER_CONTEXT
553         StartSubRenderThread(PARALLEL_THREAD_NUM,
554             renderEngine->GetRenderContext(), renderEngine->GetDrawingContext());
555 #else
556         StartSubRenderThread(PARALLEL_THREAD_NUM,
557             renderEngine->GetRenderContext().get());
558 #endif
559     } else {
560         EndSubRenderThread();
561     }
562 }
563 
CommitSurfaceNum(int surfaceNum)564 void RSParallelRenderManager::CommitSurfaceNum(int surfaceNum)
565 {
566     if (ParallelRenderExtEnabled() && (RSParallelRenderExt::setCoreLevelFunc_ != nullptr)) {
567         auto setCoreLevel = reinterpret_cast<void(*)(int)>(RSParallelRenderExt::setCoreLevelFunc_);
568         setCoreLevel(surfaceNum);
569     }
570 }
571 
WorkSerialTask(RSSurfaceRenderNode & node)572 void RSParallelRenderManager::WorkSerialTask(RSSurfaceRenderNode &node)
573 {
574     if (uniVisitor_) {
575         uniVisitor_->PrepareSurfaceRenderNode(node);
576     }
577 }
578 
GetParallelThreadNumber() const579 uint32_t RSParallelRenderManager::GetParallelThreadNumber() const
580 {
581     return PARALLEL_THREAD_NUM;
582 }
583 
AddSelfDrawingSurface(unsigned int subThreadIndex,bool isRRect,RectF rect,Vector4f cornerRadius)584 void RSParallelRenderManager::AddSelfDrawingSurface(unsigned int subThreadIndex, bool isRRect, RectF rect,
585     Vector4f cornerRadius)
586 {
587     if (parallelHardwareComposer_) {
588         auto shape = std::make_unique<RSParallelSelfDrawingSurfaceShape>(isRRect, rect, cornerRadius);
589         parallelHardwareComposer_->AddTransparentColorArea(subThreadIndex, std::move(shape));
590     }
591 }
592 
ClearSelfDrawingSurface(RSPaintFilterCanvas & canvas,unsigned int subThreadIndex)593 void RSParallelRenderManager::ClearSelfDrawingSurface(RSPaintFilterCanvas& canvas, unsigned int subThreadIndex)
594 {
595     if (parallelHardwareComposer_) {
596         parallelHardwareComposer_->ClearTransparentColor(canvas, subThreadIndex);
597     }
598 }
599 
WaitCalcCostEnd()600 void RSParallelRenderManager::WaitCalcCostEnd()
601 {
602     for (uint32_t i = 0; i < expectedSubThreadNum_; ++i) {
603         WaitSubMainThread(i);
604     }
605 }
606 
GetCostFactor()607 void RSParallelRenderManager::GetCostFactor()
608 {
609     if (costFactor_.size() > 0 && imageFactor_.size() > 0) {
610         return;
611     }
612     calcCostTaskManager_.GetCostFactor(costFactor_, imageFactor_);
613 }
614 
GetCost(RSRenderNode & node) const615 int32_t RSParallelRenderManager::GetCost(RSRenderNode &node) const
616 {
617     int32_t cost = 1;
618     const auto& property = node.GetRenderProperties();
619     if (ROSEN_EQ(property.GetAlpha(), 1.0f)) {
620         cost += costFactor_.count("alpha") > 0 ? costFactor_.find("alpha")->second : 1;
621     }
622     if (property.NeedFilter()) {
623         cost += costFactor_.count("filter") > 0 ? costFactor_.find("filter")->second : 1;
624     }
625     if (property.GetBgImage() != nullptr) {
626         int64_t size = floor(property.GetBgImageHeight() * property.GetBgImageWidth());
627         for (const auto &[imageSize, imageCost] : imageFactor_) {
628             if (size <= imageSize) {
629                 cost += imageCost;
630                 break;
631             }
632         }
633     }
634     return cost;
635 }
636 
GetSelfDrawNodeCost() const637 int32_t RSParallelRenderManager::GetSelfDrawNodeCost() const
638 {
639     return costFactor_.count("selfDraw") > 0 ? costFactor_.find("selfDraw")->second : 1;
640 }
641 
UpdateNodeCost(RSDisplayRenderNode & node)642 void RSParallelRenderManager::UpdateNodeCost(RSDisplayRenderNode &node)
643 {
644     parallelPolicy_.clear();
645     calcCostTaskManager_.UpdateNodeCost(node, parallelPolicy_);
646 }
647 
AddAppWindowNode(uint32_t surfaceIndex,std::shared_ptr<RSSurfaceRenderNode> appNode)648 void RSParallelRenderManager::AddAppWindowNode(uint32_t surfaceIndex, std::shared_ptr<RSSurfaceRenderNode> appNode)
649 {
650     if (surfaceIndex < PARALLEL_THREAD_NUM) {
651         appWindowNodesMap_[surfaceIndex].emplace_back(appNode);
652     }
653 }
654 
InitDisplayNodeAndRequestFrame(const std::shared_ptr<RSBaseRenderEngine> renderEngine,const ScreenInfo screenInfo)655 void RSParallelRenderManager::InitDisplayNodeAndRequestFrame(
656     const std::shared_ptr<RSBaseRenderEngine> renderEngine, const ScreenInfo screenInfo)
657 {
658 #ifdef RS_ENABLE_VK
659     auto& context = RSMainThread::Instance()->GetContext();
660     parallelFrames_.clear();
661     std::swap(parallelDisplayNodes_, backParallelDisplayNodes_);
662     for (int i = 0; i < PARALLEL_THREAD_NUM; i++) {
663         if(!parallelDisplayNodes_[i]) {
664             RSDisplayNodeConfig config;
665             parallelDisplayNodes_[i] =
666                 std::make_shared<RSDisplayRenderNode>(i, config, context.weak_from_this());
667             parallelDisplayNodes_[i]->SetIsParallelDisplayNode(true);
668         }
669         if (!parallelDisplayNodes_[i]->IsSurfaceCreated()) {
670             sptr<IBufferConsumerListener> listener = new RSUniRenderListener(parallelDisplayNodes_[i]);
671             if (!parallelDisplayNodes_[i]->CreateSurface(listener)) {
672                 RS_LOGE("RSParallelRenderManager::InitDisplayNodeAndRequestFrame CreateSurface failed");
673                 return;
674             }
675         }
676         auto rsSurface = parallelDisplayNodes_[i]->GetRSSurface();
677         if (rsSurface == nullptr) {
678             RS_LOGE("RSParallelRenderManager::InitDisplayNodeAndRequestFrame No RSSurface found");
679             return;
680         }
681         rsSurface->SetColorSpace(uniVisitor_->GetColorGamut());
682         std::unique_ptr<RSRenderFrame> renderFrame =
683             renderEngine->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface),
684             RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo, true));
685         parallelFrames_.push_back(std::move(renderFrame));
686     }
687 #endif
688 }
689 
ProcessParallelDisplaySurface(RSUniRenderVisitor & visitor)690 void RSParallelRenderManager::ProcessParallelDisplaySurface(RSUniRenderVisitor &visitor)
691 {
692 #ifdef RS_ENABLE_VK
693     for (int i = 0; i < PARALLEL_THREAD_NUM; i++) {
694         if (!parallelDisplayNodes_[i]) {
695             continue;
696         }
697         visitor.GetProcessor()->ProcessDisplaySurface(*parallelDisplayNodes_[i]);
698     }
699 #endif
700 }
701 
ReleaseBuffer()702 void RSParallelRenderManager::ReleaseBuffer()
703 {
704 #ifdef RS_ENABLE_VK
705     for (int i = 0; i < PARALLEL_THREAD_NUM; i++) {
706         if (!parallelDisplayNodes_[i]) {
707             continue;
708         }
709         auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*parallelDisplayNodes_[i]);
710         (void)RSBaseRenderUtil::ReleaseBuffer(surfaceHandler);
711     }
712 #endif
713 }
714 
NotifyUniRenderFinish()715 void RSParallelRenderManager::NotifyUniRenderFinish()
716 {
717 #ifdef RS_ENABLE_VK
718     readyBufferNum_++;
719     if (readyBufferNum_ == PARALLEL_THREAD_NUM) {
720         RS_TRACE_NAME("RSParallelRenderManager::NotifyUniRenderFinish");
721         RSMainThread::Instance()->NotifyUniRenderFinish();
722         readyBufferNum_ = 0;
723     }
724 #endif
725 }
726 
GetParallelDisplayNode(uint32_t subMainThreadIdx)727 std::shared_ptr<RSDisplayRenderNode> RSParallelRenderManager::GetParallelDisplayNode(
728     uint32_t subMainThreadIdx)
729 {
730 #ifdef RS_ENABLE_VK
731     return parallelDisplayNodes_[subMainThreadIdx];
732 #else
733     return nullptr;
734 #endif
735 }
736 
GetParallelFrame(uint32_t subMainThreadIdx)737 std::unique_ptr<RSRenderFrame> RSParallelRenderManager::GetParallelFrame(
738     uint32_t subMainThreadIdx)
739 {
740 #ifdef RS_ENABLE_VK
741     return std::move(parallelFrames_[subMainThreadIdx]);
742 #else
743     return nullptr;
744 #endif
745 }
746 
ProcessFilterSurfaceRenderNode()747 void RSParallelRenderManager::ProcessFilterSurfaceRenderNode()
748 {
749     if (GetParallelModeSafe()) {
750         for (auto& node : filterSurfaceRenderNodes_) {
751             node->Process(uniVisitor_->shared_from_this());
752         }
753     }
754 }
755 } // namespace Rosen
756 } // namespace OHOS