• 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 #define EGL_EGLEXT_PROTOTYPES
17 #include "rs_parallel_sub_thread.h"
18 #include <cstddef>
19 #include <memory>
20 #include <mutex>
21 #include <string>
22 #include <sys/resource.h>
23 #include <sys/ioctl.h>
24 #include "GLES3/gl3.h"
25 #include "include/core/SkCanvas.h"
26 #include "include/core/SkColor.h"
27 #include "include/core/SkRect.h"
28 #include "EGL/egl.h"
29 #include "rs_trace.h"
30 #include "pipeline/rs_canvas_render_node.h"
31 #include "pipeline/rs_display_render_node.h"
32 #include "pipeline/rs_surface_render_node.h"
33 #include "rs_node_cost_manager.h"
34 #include "rs_parallel_render_manager.h"
35 #include "common/rs_obj_abs_geometry.h"
36 #include "pipeline/rs_uni_render_visitor.h"
37 #include "rs_parallel_render_ext.h"
38 #include "pipeline/rs_main_thread.h"
39 #include "pipeline/rs_uni_render_engine.h"
40 
41 namespace OHOS {
42 namespace Rosen {
RSParallelSubThread(int threadIndex)43 RSParallelSubThread::RSParallelSubThread(int threadIndex)
44     : threadIndex_(threadIndex), subThread_(nullptr), renderType_(ParallelRenderType::DRAW_IMAGE) {}
45 #ifdef NEW_RENDER_CONTEXT
RSParallelSubThread(std::shared_ptr<RenderContextBase> context,ParallelRenderType renderType,int threadIndex)46 RSParallelSubThread::RSParallelSubThread(std::shared_ptr<RenderContextBase> context,
47     ParallelRenderType renderType, int threadIndex) : threadIndex_(threadIndex), subThread_(nullptr),
48     renderContext_(context), renderType_(renderType) {}
49 #else
RSParallelSubThread(RenderContext * context,ParallelRenderType renderType,int threadIndex)50 RSParallelSubThread::RSParallelSubThread(RenderContext *context, ParallelRenderType renderType, int threadIndex)
51     : threadIndex_(threadIndex), subThread_(nullptr), renderContext_(context), renderType_(renderType) {}
52 #endif
~RSParallelSubThread()53 RSParallelSubThread::~RSParallelSubThread()
54 {
55     if (renderContext_ != nullptr) {
56 #ifdef NEW_RENDER_CONTEXT
57         auto frame = renderContext_->GetRSRenderSurfaceFrame();
58         EGLDisplay eglDisplay = frame->eglState->eglDisplay;
59         eglDestroyContext(eglDisplay, eglShareContext_);
60         eglShareContext_ = EGL_NO_CONTEXT;
61         eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
62 #else
63         eglDestroyContext(renderContext_->GetEGLDisplay(), eglShareContext_);
64         eglShareContext_ = EGL_NO_CONTEXT;
65         eglMakeCurrent(renderContext_->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
66 #endif
67     }
68     texture_ = nullptr;
69     canvas_ = nullptr;
70 #ifndef USE_ROSEN_DRAWING
71     skSurface_ = nullptr;
72 #else
73     surface_ = nullptr;
74 #endif
75     RS_LOGI("~RSParallelSubThread():%{public}d", threadIndex_);
76 }
77 
MainLoopHandlePrepareTask()78 void RSParallelSubThread::MainLoopHandlePrepareTask()
79 {
80     RS_TRACE_BEGIN("SubThreadCostPrepare[" + std::to_string(threadIndex_) + "]");
81     StartPrepare();
82     Prepare();
83     RSParallelRenderManager::Instance()->SubMainThreadNotify(threadIndex_);
84     RS_TRACE_END();
85 }
86 
MainLoop()87 void RSParallelSubThread::MainLoop()
88 {
89     InitSubThread();
90 #ifdef RS_ENABLE_GL
91     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
92         CreateShareEglContext();
93     }
94 #endif
95     while (true) {
96         WaitTaskSync();
97         if (RSParallelRenderManager::Instance()->GetParallelRenderingStatus() == ParallelStatus::OFF) {
98             return;
99         }
100         // parallel rendering will be enable when the windows number is greater than 50
101         RSParallelRenderManager::Instance()->CommitSurfaceNum(50);
102         switch (RSParallelRenderManager::Instance()->GetTaskType()) {
103             case TaskType::PREPARE_TASK: {
104                 MainLoopHandlePrepareTask();
105                 break;
106             }
107             case TaskType::CALC_COST_TASK: {
108                 RS_TRACE_BEGIN("SubThreadCalcCost[" + std::to_string(threadIndex_) + "]");
109                 CalcCost();
110                 RSParallelRenderManager::Instance()->SubMainThreadNotify(threadIndex_);
111                 RS_TRACE_END();
112                 break;
113             }
114             case TaskType::PROCESS_TASK: {
115                 RS_TRACE_BEGIN("SubThreadCostProcess[" + std::to_string(threadIndex_) + "]");
116                 StartRender();
117                 Render();
118                 ParallelStatus status = RSParallelRenderManager::Instance()->GetParallelRenderingStatus();
119                 if (status == ParallelStatus::FIRSTFLUSH || status == ParallelStatus::WAITFIRSTFLUSH) {
120                     RSParallelRenderManager::Instance()->SubMainThreadNotify(threadIndex_);
121                 }
122                 RS_TRACE_END();
123                 Flush();
124                 break;
125             }
126             case TaskType::COMPOSITION_TASK: {
127                 StartComposition();
128                 Composition();
129                 RSParallelRenderManager::Instance()->SubMainThreadNotify(threadIndex_);
130                 break;
131             }
132             default: {
133                 break;
134             }
135         }
136     }
137 }
138 
StartSubThread()139 void RSParallelSubThread::StartSubThread()
140 {
141     subThread_ = new std::thread(&RSParallelSubThread::MainLoop, this);
142 }
143 
WaitTaskSync()144 void RSParallelSubThread::WaitTaskSync()
145 {
146     RSParallelRenderManager::Instance()->SubMainThreadWait(threadIndex_);
147 }
148 
InitSubThread()149 void RSParallelSubThread::InitSubThread()
150 {
151     pthread_setname_np(pthread_self(), "SubMainThread");
152     struct sched_param param = {0};
153     // sched_priority interval: [1, 99]; higher number refers to a higher thread priority,
154     // set 2 as experience reference.
155     param.sched_priority = 2;
156     (void)sched_setscheduler(0, SCHED_FIFO, &param);
157 }
158 
CreateShareEglContext()159 void RSParallelSubThread::CreateShareEglContext()
160 {
161 #ifdef RS_ENABLE_GL
162     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
163         return;
164     }
165     if (renderContext_ == nullptr) {
166         RS_LOGE("renderContext_ is nullptr");
167         return;
168     }
169 #ifdef NEW_RENDER_CONTEXT
170     eglShareContext_ = renderContext_->CreateContext(true);
171 #else
172     eglShareContext_ = renderContext_->CreateShareContext();
173 #endif
174     if (eglShareContext_ == EGL_NO_CONTEXT) {
175         RS_LOGE("eglShareContext_ is EGL_NO_CONTEXT");
176         return;
177     }
178     if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
179 #ifdef NEW_RENDER_CONTEXT
180         auto frame = renderContext_->GetRSRenderSurfaceFrame();
181         EGLDisplay eglDisplay = frame->eglState->eglDisplay;
182         if (!eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglShareContext_)) {
183 #else
184         if (!eglMakeCurrent(renderContext_->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, eglShareContext_)) {
185 #endif
186             RS_LOGE("eglMakeCurrent failed");
187             return;
188         }
189     }
190 #endif
191 }
192 
193 void RSParallelSubThread::StartPrepare()
194 {
195     InitUniVisitor();
196 }
197 
198 void RSParallelSubThread::InitUniVisitor()
199 {
200     RSUniRenderVisitor *uniVisitor = RSParallelRenderManager::Instance()->GetUniVisitor();
201     if (uniVisitor == nullptr) {
202         RS_LOGE("uniVisitor is nullptr");
203         return;
204     }
205     visitor_ = std::make_shared<RSUniRenderVisitor>(*uniVisitor);
206 }
207 
208 void RSParallelSubThread::Prepare()
209 {
210     if (threadTask_ == nullptr) {
211         RS_LOGE("threadTask is nullptr");
212         return;
213     }
214     while (threadTask_->GetTaskSize() > 0) {
215         RSParallelRenderManager::Instance()->StartTiming(threadIndex_);
216         auto task = threadTask_->GetNextRenderTask();
217         if (!task || (task->GetIdx() == 0)) {
218             RS_LOGE("surfaceNode is nullptr");
219             continue;
220         }
221         auto node = task->GetNode();
222         if (!node) {
223             RS_LOGE("surfaceNode is nullptr");
224             continue;
225         }
226         node->Prepare(visitor_);
227         RSParallelRenderManager::Instance()->StopTimingAndSetRenderTaskCost(
228             threadIndex_, task->GetIdx(), TaskType::PREPARE_TASK);
229     }
230 }
231 
232 void RSParallelSubThread::CalcCost()
233 {
234     if (threadTask_ == nullptr) {
235         RS_LOGE("CalcCost thread task is null");
236         return;
237     }
238     RSUniRenderVisitor *uniVisitor = RSParallelRenderManager::Instance()->GetUniVisitor();
239     if (uniVisitor == nullptr) {
240         RS_LOGE("CalcCost visitor is null");
241         return;
242     }
243     std::shared_ptr<RSNodeCostManager> manager = std::make_shared<RSNodeCostManager>(
244         RSParallelRenderManager::Instance()->IsDoAnimate(),
245         RSParallelRenderManager::Instance()->IsOpDropped(),
246         RSParallelRenderManager::Instance()->IsSecurityDisplay());
247 
248     while (threadTask_->GetTaskSize() > 0) {
249         RSParallelRenderManager::Instance()->StartTiming(threadIndex_);
250         auto task = threadTask_->GetNextRenderTask();
251         if (task == nullptr || task->GetIdx() == 0) {
252             RS_LOGI("CalcCost task is invalid");
253             continue;
254         }
255         auto node = task->GetNode();
256         if (node == nullptr) {
257             RS_LOGI("CalcCost node is null");
258             continue;
259         }
260         auto surfaceNodePtr = node->ReinterpretCastTo<RSSurfaceRenderNode>();
261         if (surfaceNodePtr == nullptr) {
262             RS_LOGI("CalcCost surface node is null");
263             continue;
264         }
265         manager->CalcNodeCost(*surfaceNodePtr);
266         surfaceNodePtr->SetNodeCost(manager->GetDirtyNodeCost());
267         RSParallelRenderManager::Instance()->StopTimingAndSetRenderTaskCost(
268             threadIndex_, task->GetIdx(), TaskType::CALC_COST_TASK);
269     }
270 }
271 
272 void RSParallelSubThread::StartRender()
273 {
274     CreateResource();
275 }
276 
277 void RSParallelSubThread::Render()
278 {
279     if (threadTask_ == nullptr) {
280         RS_LOGE("threadTask is nullptr");
281         return;
282     }
283     auto physicalDisplayNode = std::static_pointer_cast<RSDisplayRenderNode>(threadTask_->GetNode());
284     auto physicalGeoPtr = (
285         physicalDisplayNode->GetRenderProperties().GetBoundsGeometry());
286 #ifdef RS_ENABLE_GL
287     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
288         if (canvas_ == nullptr) {
289             RS_LOGE("Canvas is nullptr");
290             return;
291         }
292 #ifndef USE_ROSEN_DRAWING
293         int saveCount = canvas_->save();
294         if (RSMainThread::Instance()->GetRenderEngine()) {
295             canvas_->SetHighContrast(RSMainThread::Instance()->GetRenderEngine()->IsHighContrastEnabled());
296         }
297         if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
298             canvas_->clear(SK_ColorTRANSPARENT);
299         }
300         canvas_->save();
301         if (physicalGeoPtr != nullptr) {
302             canvas_->concat(physicalGeoPtr->GetMatrix());
303             canvas_->SetCacheType(RSSystemProperties::GetCacheEnabledForRotation() ?
304                 RSPaintFilterCanvas::CacheType::ENABLED : RSPaintFilterCanvas::CacheType::DISABLED);
305         }
306 #else
307         auto saveCount = canvas_->Save();
308         if (RSMainThread::Instance()->GetRenderEngine()) {
309             canvas_->SetHighContrast(RSMainThread::Instance()->GetRenderEngine()->IsHighContrastEnabled());
310         }
311         if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
312             canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
313         }
314         canvas_->Save();
315         if (physicalGeoPtr != nullptr) {
316             canvas_->ConcatMatrix(physicalGeoPtr->GetMatrix());
317             canvas_->SetCacheType(RSSystemProperties::GetCacheEnabledForRotation() ?
318                 RSPaintFilterCanvas::CacheType::ENABLED : RSPaintFilterCanvas::CacheType::DISABLED);
319         }
320 #endif
321         while (threadTask_->GetTaskSize() > 0) {
322             RSParallelRenderManager::Instance()->StartTiming(threadIndex_);
323             auto task = threadTask_->GetNextRenderTask();
324             if (!task || (task->GetIdx() == 0)) {
325                 RS_LOGE("renderTask is nullptr");
326                 continue;
327             }
328             auto node = task->GetNode();
329             if (!node) {
330                 RS_LOGE("surfaceNode is nullptr");
331                 continue;
332             }
333             node->Process(visitor_);
334             RSParallelRenderManager::Instance()->StopTimingAndSetRenderTaskCost(
335                 threadIndex_, task->GetIdx(), TaskType::PROCESS_TASK);
336         }
337 #ifndef USE_ROSEN_DRAWING
338         canvas_->restoreToCount(saveCount);
339 #else
340         canvas_->RestoreToCount(saveCount);
341 #endif
342     }
343 #endif
344 
345 #ifdef RS_ENABLE_VK
346     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
347         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
348         if (!displayNode_) {
349             RS_LOGE("RSParallelSubThread::Render displayNode_ nullptr");
350             return;
351         }
352         displayNode_->SetScreenId(physicalDisplayNode->GetScreenId());
353         displayNode_->SetDisplayOffset(
354             physicalDisplayNode->GetDisplayOffsetX(), physicalDisplayNode->GetDisplayOffsetY());
355         displayNode_->SetForceSoftComposite(physicalDisplayNode->IsForceSoftComposite());
356         auto geoPtr = (
357             displayNode_->GetRenderProperties().GetBoundsGeometry());
358         if (physicalGeoPtr && geoPtr) {
359             *geoPtr = *physicalGeoPtr;
360             geoPtr->UpdateByMatrixFromSelf();
361         }
362         while (threadTask_->GetTaskSize() > 0) {
363             auto task = threadTask_->GetNextRenderTask();
364             if (!task || (task->GetIdx() == 0)) {
365                 RS_LOGE("renderTask is nullptr");
366                 continue;
367             }
368             auto node = task->GetNode();
369             if (!node) {
370                 RS_LOGE("surfaceNode is nullptr");
371                 continue;
372             }
373             displayNode_->AddCrossParentChild(node);
374         }
375         displayNode_->Process(visitor_);
376         for (auto& child : *displayNode_->GetChildren()) {
377             displayNode_->RemoveCrossParentChild(child, physicalDisplayNode);
378         }
379     }
380 #endif
381 }
382 
383 #ifdef USE_ROSEN_DRAWING
384 bool RSParallelSubThread::FlushForRosenDrawing()
385 {
386     if (drCanvas_ == nullptr) {
387         RS_LOGE("in Flush(), drCanvas is nullptr");
388         return false;
389     }
390     if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
391         RS_TRACE_BEGIN("Flush");
392         if (drContext_) {
393             drContext_->FlushAndSubmit(false);
394         }
395         RS_TRACE_END();
396         RS_TRACE_BEGIN("Create Fence");
397 #ifdef NEW_RENDER_CONTEXT
398         if (renderContext_ == nullptr) {
399             RS_LOGE("renderContext_ is nullptr");
400             return false;
401         }
402         auto frame = renderContext_->GetRSRenderSurfaceFrame();
403         EGLDisplay eglDisplay = frame->eglState->eglDisplay;
404         eglSync_ = eglCreateSyncKHR(eglDisplay, EGL_SYNC_FENCE_KHR, nullptr);
405 #else
406         eglSync_ = eglCreateSyncKHR(renderContext_->GetEGLDisplay(), EGL_SYNC_FENCE_KHR, nullptr);
407 #endif
408         RS_TRACE_END();
409         texture_ = surface_->GetImageSnapshot();
410         drCanvas_->Discard();
411     }
412     return true;
413 }
414 #endif
415 
416 void RSParallelSubThread::Flush()
417 {
418     threadTask_ = nullptr;
419 #ifdef RS_ENABLE_GL
420     if (RSSystemProperties::GetGpuApiType() != GpuApiType::VULKAN &&
421         RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
422 #ifndef USE_ROSEN_DRAWING
423         if (skCanvas_ == nullptr) {
424             RS_LOGE("in Flush(), skCanvas is nullptr");
425             return;
426         }
427         if (renderType_ == ParallelRenderType::DRAW_IMAGE) {
428             RS_TRACE_BEGIN("Flush");
429             if (grContext_) {
430                 grContext_->flushAndSubmit(false);
431             }
432             RS_TRACE_END();
433             RS_TRACE_BEGIN("Create Fence");
434 #ifdef NEW_RENDER_CONTEXT
435             auto frame = renderContext_->GetRSRenderSurfaceFrame();
436             EGLDisplay eglDisplay = frame->eglState->eglDisplay;
437             eglSync_ = eglCreateSyncKHR(eglDisplay, EGL_SYNC_FENCE_KHR, nullptr);
438 #else
439             eglSync_ = eglCreateSyncKHR(renderContext_->GetEGLDisplay(), EGL_SYNC_FENCE_KHR, nullptr);
440 #endif
441             RS_TRACE_END();
442             texture_ = skSurface_->makeImageSnapshot();
443             skCanvas_->discard();
444         }
445 #else
446         if (!FlushForRosenDrawing()) {
447             return;
448         }
449 #endif
450     }
451 #endif
452     // FIRSTFLUSH or WAITFIRSTFLUSH
453     ParallelStatus parallelStatus = RSParallelRenderManager::Instance()->GetParallelRenderingStatus();
454     if (parallelStatus == ParallelStatus::FIRSTFLUSH || parallelStatus == ParallelStatus::WAITFIRSTFLUSH) {
455         RSParallelRenderManager::Instance()->ReadySubThreadNumIncrement();
456     } else {
457         RSParallelRenderManager::Instance()->SubMainThreadNotify(threadIndex_);
458     }
459 }
460 
461 bool RSParallelSubThread::WaitReleaseFence()
462 {
463     if (eglSync_ != EGL_NO_SYNC_KHR) {
464 #ifdef NEW_RENDER_CONTEXT
465         if (renderContext_ == nullptr) {
466             RS_LOGE("renderContext_ is nullptr");
467             return false;
468         }
469         auto frame = renderContext_->GetRSRenderSurfaceFrame();
470         EGLDisplay eglDisplay = frame->eglState->eglDisplay;
471         EGLint ret = eglWaitSyncKHR(eglDisplay, eglSync_, 0);
472 #else
473         EGLint ret = eglWaitSyncKHR(renderContext_->GetEGLDisplay(), eglSync_, 0);
474 #endif
475         if (ret == EGL_FALSE) {
476             ROSEN_LOGE("eglClientWaitSyncKHR error 0x%{public}x", eglGetError());
477             return false;
478         } else if (ret == EGL_TIMEOUT_EXPIRED_KHR) {
479             ROSEN_LOGE("create eglClientWaitSyncKHR timeout");
480             return false;
481         }
482 #ifdef NEW_RENDER_CONTEXT
483         eglDestroySyncKHR(eglDisplay, eglSync_);
484 #else
485         eglDestroySyncKHR(renderContext_->GetEGLDisplay(), eglSync_);
486 #endif
487     }
488     eglSync_ = EGL_NO_SYNC_KHR;
489     return true;
490 }
491 
492 void RSParallelSubThread::CreateResource()
493 {
494 #ifdef RS_ENABLE_GL
495     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
496         int width, height;
497         RSParallelRenderManager::Instance()->GetFrameSize(width, height);
498         if (width != surfaceWidth_ || height != surfaceHeight_) {
499             RS_LOGE("CreateResource %{public}d, new size [%{public}d, %{public}d], old size [%{public}d, %{public}d]",
500                 threadIndex_, width, height, surfaceWidth_, surfaceHeight_);
501             surfaceWidth_ = width;
502             surfaceHeight_ = height;
503 #ifndef USE_ROSEN_DRAWING
504             AcquireSubSkSurface(surfaceWidth_, surfaceHeight_);
505             if (skSurface_ == nullptr) {
506                 RS_LOGE("in CreateResource, skSurface is nullptr");
507                 return;
508             }
509             skCanvas_ = skSurface_->getCanvas();
510             canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_);
511             canvas_->SetIsParallelCanvas(true);
512 #else
513             AcquireSubDrawingSurface(surfaceWidth_, surfaceHeight_);
514             if (surface_ == nullptr) {
515                 RS_LOGE("in CreateResource, surface_ is nullptr");
516                 return;
517             }
518             drCanvas_ = surface_->GetCanvas().get();
519             canvas_ = std::make_shared<RSPaintFilterCanvas>(drCanvas_);
520             canvas_->SetIsParallelCanvas(true);
521 #endif
522         }
523         visitor_ = std::make_shared<RSUniRenderVisitor>(canvas_, threadIndex_);
524     }
525 #endif
526 
527 #ifdef RS_ENABLE_VK
528     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
529         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
530         displayNode_ = RSParallelRenderManager::Instance()->GetParallelDisplayNode(threadIndex_);
531         if (!displayNode_) {
532             RS_LOGE("RSParallelSubThread::CreateResource displayNode_ nullptr");
533             return;
534         }
535         visitor_ = std::make_shared<RSUniRenderVisitor>(nullptr, threadIndex_);
536         visitor_->SetRenderFrame(
537             RSParallelRenderManager::Instance()->GetParallelFrame(threadIndex_));
538     }
539 #endif
540     visitor_->CopyPropertyForParallelVisitor(
541         RSParallelRenderManager::Instance()->GetUniVisitor());
542 }
543 
544 #ifndef USE_ROSEN_DRAWING
545 #ifdef NEW_SKIA
546 sk_sp<GrDirectContext> RSParallelSubThread::CreateShareGrContext()
547 #else
548 sk_sp<GrContext> RSParallelSubThread::CreateShareGrContext()
549 #endif
550 {
551     const GrGLInterface *grGlInterface = GrGLCreateNativeInterface();
552     sk_sp<const GrGLInterface> glInterface(grGlInterface);
553     if (glInterface.get() == nullptr) {
554         RS_LOGE("CreateShareGrContext failed");
555         return nullptr;
556     }
557 
558     GrContextOptions options = {};
559     options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
560     // fix svg antialiasing bug
561     options.fGpuPathRenderers &= ~GpuPathRenderers::kAtlas;
562     options.fPreferExternalImagesOverES3 = true;
563     options.fDisableDistanceFieldPaths = true;
564 #ifdef NEW_SKIA
565     sk_sp<GrDirectContext> grContext = GrDirectContext::MakeGL(std::move(glInterface), options);
566 #else
567     sk_sp<GrContext> grContext = GrContext::MakeGL(std::move(glInterface), options);
568 #endif
569     if (grContext == nullptr) {
570         RS_LOGE("nullptr grContext is null");
571         return nullptr;
572     }
573     return grContext;
574 }
575 #else
576 std::shared_ptr<Drawing::GPUContext> RSParallelSubThread::CreateShareGPUContext()
577 {
578     auto drGPUContext = std::make_shared<Drawing::GPUContext>();
579     Drawing::GPUContextOptions options;
580     drGPUContext->BuildFromGL(options);
581     return drGPUContext;
582 }
583 #endif
584 
585 #ifndef USE_ROSEN_DRAWING
586 void RSParallelSubThread::AcquireSubSkSurface(int width, int height)
587 {
588     if (grContext_ == nullptr) {
589         grContext_ = CreateShareGrContext();
590     }
591 
592     if (grContext_ == nullptr) {
593         RS_LOGE("Share GrContext is not ready!!!");
594         return;
595     }
596 
597     auto surfaceInfo = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
598     skSurface_ = SkSurface::MakeRenderTarget(grContext_.get(), SkBudgeted::kYes, surfaceInfo);
599     if (skSurface_ == nullptr) {
600         RS_LOGE("skSurface is not ready!!!");
601         return;
602     }
603 }
604 #else
605 void RSParallelSubThread::AcquireSubDrawingSurface(int width, int height)
606 {
607     if (drContext_ == nullptr) {
608         drContext_ = CreateShareGPUContext();
609     }
610 
611     if (drContext_ == nullptr) {
612         RS_LOGE("Share GrContext is not ready!!!");
613         return;
614     }
615 
616     Drawing::ImageInfo surfaceInfo =
617         Drawing::ImageInfo{width, height, Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL};
618     surface_ = Drawing::Surface::MakeRenderTarget(drContext_.get(), true, surfaceInfo);
619     if (surface_ == nullptr) {
620         RS_LOGE("surface is not ready!!!");
621         return;
622     }
623 }
624 #endif
625 
626 void RSParallelSubThread::StartComposition()
627 {
628     if (processorRenderEngine_ == nullptr) {
629         processorRenderEngine_ = std::make_shared<RSUniRenderEngine>();
630         processorRenderEngine_->Init();
631         auto context = processorRenderEngine_->GetRenderContext();
632         context->SetAndMakeCurrentShareContex(eglShareContext_);
633     }
634     compositionVisitor_ = std::make_shared<RSUniRenderVisitor>();
635     auto parallelRenderManager = RSParallelRenderManager::Instance();
636     if (parallelRenderManager->GetUniParallelCompositionVisitor() != nullptr) {
637         compositionVisitor_->CopyVisitorInfos(parallelRenderManager->GetUniParallelCompositionVisitor());
638     } else {
639         compositionVisitor_ = nullptr;
640     }
641 }
642 
643 void RSParallelSubThread::Composition()
644 {
645     if (compositionTask_ == nullptr || compositionTask_->GetIdx() == 0) {
646         RS_LOGE("compositionTask is nullptr or displayNodeId is 0");
647         return;
648     }
649 
650     auto node = compositionTask_->GetNode();
651     if (node == nullptr || compositionVisitor_ == nullptr) {
652         RS_LOGE("displayNode or visitor is nullptr.");
653         return;
654     }
655 
656     compositionVisitor_->SetProcessorRenderEngine(processorRenderEngine_);
657     node->Process(compositionVisitor_);
658     compositionVisitor_ = nullptr;
659     compositionTask_ = nullptr;
660 }
661 
662 EGLContext RSParallelSubThread::GetSharedContext() const
663 {
664     return eglShareContext_;
665 }
666 
667 #ifndef USE_ROSEN_DRAWING
668 sk_sp<SkSurface> RSParallelSubThread::GetSkSurface() const
669 {
670     return skSurface_;
671 }
672 #else
673 std::shared_ptr<Drawing::Surface> RSParallelSubThread::GetDrawingSurface() const
674 {
675     return surface_;
676 }
677 #endif
678 
679 void RSParallelSubThread::SetSuperTask(std::unique_ptr<RSSuperRenderTask> superRenderTask)
680 {
681     threadTask_ = std::move(superRenderTask);
682 }
683 
684 void RSParallelSubThread::SetCompositionTask(std::unique_ptr<RSCompositionTask> compositionTask)
685 {
686     compositionTask_ = std::move(compositionTask);
687 }
688 
689 #ifndef USE_ROSEN_DRAWING
690 sk_sp<SkImage> RSParallelSubThread::GetTexture() const
691 #else
692 std::shared_ptr<Drawing::Image> RSParallelSubThread::GetTexture() const
693 #endif
694 {
695     return texture_;
696 }
697 } // namespace Rosen
698 } // namespace OHOS