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