1 /*
2  * Copyright (c) 2024 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 <memory>
17 
18 #include "impl_interface/region_impl.h"
19 #include "rs_trace.h"
20 
21 #include "common/rs_color.h"
22 #include "common/rs_common_def.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "draw/brush.h"
25 #include "drawable/rs_surface_render_node_drawable.h"
26 #include "memory/rs_tag_tracker.h"
27 #include "params/rs_display_render_params.h"
28 #include "params/rs_surface_render_params.h"
29 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
30 #include "pipeline/rs_main_thread.h"
31 #include "pipeline/rs_paint_filter_canvas.h"
32 #include "pipeline/rs_surface_render_node.h"
33 #include "pipeline/rs_uifirst_manager.h"
34 #include "pipeline/rs_uni_render_thread.h"
35 #include "pipeline/rs_uni_render_util.h"
36 #include "pipeline/sk_resource_manager.h"
37 #include "platform/common/rs_log.h"
38 #include "rs_profiler.h"
39 #include "rs_frame_report.h"
40 #include "utils/rect.h"
41 #include "utils/region.h"
42 #ifdef RS_ENABLE_VK
43 #include "include/gpu/GrBackendSurface.h"
44 #include "platform/ohos/backend/native_buffer_utils.h"
45 #include "platform/ohos/backend/rs_vulkan_context.h"
46 #endif
47 
48 namespace {
__anon70fde0e30202() 49 static const OHOS::Rosen::Drawing::Matrix IDENTITY_MATRIX = []() {
50     OHOS::Rosen::Drawing::Matrix matrix;
51     matrix.SetMatrix(1.0f, 0.0f, 0.0f,
52                      0.0f, 1.0f, 0.0f,
53                      0.0f, 0.0f, 1.0f);
54     return matrix;
55 }();
56 }
57 
58 namespace OHOS::Rosen::DrawableV2 {
GetCacheSurfaceProcessedStatus() const59 CacheProcessStatus RSSurfaceRenderNodeDrawable::GetCacheSurfaceProcessedStatus() const
60 {
61     return uiFirstParams.cacheProcessStatus_.load();
62 }
63 
SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)64 void RSSurfaceRenderNodeDrawable::SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)
65 {
66     uiFirstParams.cacheProcessStatus_.store(cacheProcessStatus);
67     if (cacheProcessStatus == CacheProcessStatus::DONE || cacheProcessStatus == CacheProcessStatus::SKIPPED) {
68         RSUiFirstProcessStateCheckerHelper::NotifyAll();
69     }
70 }
71 
GetCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)72 std::shared_ptr<Drawing::Surface> RSSurfaceRenderNodeDrawable::GetCacheSurface(uint32_t threadIndex,
73     bool needCheckThread, bool releaseAfterGet)
74 {
75     if (releaseAfterGet) {
76         return std::move(cacheSurface_);
77     }
78     if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
79         return cacheSurface_;
80     }
81 
82     // freeze cache scene
83     ClearCacheSurfaceInThread();
84     return nullptr;
85 }
86 
ClearCacheSurfaceInThread()87 void RSSurfaceRenderNodeDrawable::ClearCacheSurfaceInThread()
88 {
89     if (UseDmaBuffer()) {
90         ClearBufferQueue();
91     } else {
92         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
93         if (clearCacheSurfaceFunc_) {
94             clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
95                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
96         }
97         ClearCacheSurface();
98     }
99 }
100 
ClearCacheSurfaceOnly()101 void RSSurfaceRenderNodeDrawable::ClearCacheSurfaceOnly()
102 {
103     RS_TRACE_NAME("ClearCacheSurfaceOnly");
104     if (cacheSurface_ == nullptr) {
105         return;
106     }
107     if (clearCacheSurfaceFunc_) {
108         clearCacheSurfaceFunc_(
109             std::move(cacheSurface_), nullptr, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
110     }
111     ClearCacheSurface(false);
112     cacheSurface_.reset();
113 }
114 
GetGravityTranslate(float imgWidth,float imgHeight)115 Vector2f RSSurfaceRenderNodeDrawable::GetGravityTranslate(float imgWidth, float imgHeight)
116 {
117     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
118     if (!surfaceParams) {
119         RS_LOGE("RSSurfaceRenderNodeDrawable::GetGravityTranslate surfaceParams is nullptr");
120         return Vector2f{};
121     }
122     auto gravity = surfaceParams->GetUIFirstFrameGravity();
123     float boundsWidth = surfaceParams->GetCacheSize().x_;
124     float boundsHeight = surfaceParams->GetCacheSize().y_;
125     Drawing::Matrix gravityMatrix;
126     RSPropertiesPainter::GetGravityMatrix(gravity, RectF {0.0f, 0.0f, boundsWidth, boundsHeight},
127         imgWidth, imgHeight, gravityMatrix);
128     return {gravityMatrix.Get(Drawing::Matrix::TRANS_X), gravityMatrix.Get(Drawing::Matrix::TRANS_Y)};
129 }
130 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)131 std::shared_ptr<Drawing::Image> RSSurfaceRenderNodeDrawable::GetCompletedImage(
132     RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
133 {
134     auto gpuContext = canvas.GetGPUContext();
135     if (!gpuContext) {
136         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage GetGPUContext nullptr");
137         return nullptr;
138     }
139     if (isUIFirst) {
140 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
141         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
142         if (!cacheCompletedBackendTexture_.IsValid()) {
143             RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage invalid grBackendTexture_");
144             return nullptr;
145         }
146         auto colorType = Drawing::COLORTYPE_RGBA_8888;
147 #ifdef RS_ENABLE_VK
148         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
149             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
150             if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
151                 RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage surface %p cleanupHelper %p",
152                     cacheCompletedSurface_.get(), cacheCompletedSurface_.get());
153                 return nullptr;
154             }
155         }
156         auto vkTexture = cacheCompletedBackendTexture_.GetTextureInfo().GetVKTextureInfo();
157         if (vkTexture != nullptr && vkTexture->format == VK_FORMAT_R16G16B16A16_SFLOAT) {
158             colorType = Drawing::ColorType::COLORTYPE_RGBA_F16;
159         }
160 #endif
161         auto image = std::make_shared<Drawing::Image>();
162         Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
163         Drawing::BitmapFormat info = Drawing::BitmapFormat{ colorType,
164             Drawing::ALPHATYPE_PREMUL };
165 #ifdef RS_ENABLE_GL
166         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
167             OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
168             image->BuildFromTexture(*gpuContext, cacheCompletedBackendTexture_.GetTextureInfo(),
169                 origin, info, nullptr);
170         }
171 #endif
172 
173 #ifdef RS_ENABLE_VK
174         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
175             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
176             image->BuildFromTexture(*gpuContext, cacheCompletedBackendTexture_.GetTextureInfo(),
177                 origin, info, nullptr,
178                 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
179         }
180 #endif
181         return image;
182 #endif
183     }
184 
185     if (!cacheCompletedSurface_) {
186         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface invalid cacheCompletedSurface");
187         return nullptr;
188     }
189     auto completeImage = cacheCompletedSurface_->GetImageSnapshot();
190     if (!completeImage) {
191         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface Get complete image failed");
192         return nullptr;
193     }
194     if (threadIndex == completedSurfaceThreadIndex_) {
195         return completeImage;
196     }
197 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
198     Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
199     auto backendTexture = completeImage->GetBackendTexture(false, &origin);
200     if (!backendTexture.IsValid()) {
201         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface get backendTexture failed");
202         return nullptr;
203     }
204     SharedTextureContext* sharedContext = new SharedTextureContext(completeImage);
205     auto cacheImage = std::make_shared<Drawing::Image>();
206     Drawing::BitmapFormat info =
207         Drawing::BitmapFormat{ completeImage->GetColorType(), completeImage->GetAlphaType() };
208     bool ret = cacheImage->BuildFromTexture(*gpuContext, backendTexture.GetTextureInfo(),
209         origin, info, nullptr, SKResourceManager::DeleteSharedTextureContext, sharedContext);
210     if (!ret) {
211         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage image BuildFromTexture failed");
212         return nullptr;
213     }
214     return cacheImage;
215 #else
216     return completeImage;
217 #endif
218 }
219 
DrawCacheSurface(RSPaintFilterCanvas & canvas,const Vector2f & boundSize,uint32_t threadIndex,bool isUIFirst)220 bool RSSurfaceRenderNodeDrawable::DrawCacheSurface(RSPaintFilterCanvas& canvas, const Vector2f& boundSize,
221     uint32_t threadIndex, bool isUIFirst)
222 {
223     if (ROSEN_EQ(boundsWidth_, 0.f) || ROSEN_EQ(boundsHeight_, 0.f)) {
224         RS_LOGE("RSSurfaceRenderNodeDrawable::DrawCacheSurface return %d", __LINE__);
225         return false;
226     }
227 
228     auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
229     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheImage, "cacheImage");
230     if (cacheImage == nullptr || ROSEN_EQ(cacheImage->GetWidth(), 0) ||
231         ROSEN_EQ(cacheImage->GetHeight(), 0)) {
232         RS_LOGE("RSSurfaceRenderNodeDrawable::DrawCacheSurface return %d", __LINE__);
233         return false;
234     }
235     float scaleX = boundSize.x_ / static_cast<float>(cacheImage->GetWidth());
236     float scaleY = boundSize.y_ / static_cast<float>(cacheImage->GetHeight());
237     canvas.Save();
238     canvas.Scale(scaleX, scaleY);
239     if (RSSystemProperties::GetRecordingEnabled()) {
240         if (cacheImage->IsTextureBacked()) {
241             RS_LOGI("RSSurfaceRenderNodeDrawable::DrawCacheSurface convert cacheImage from texture to raster image");
242             cacheImage = cacheImage->MakeRasterImage();
243         }
244     }
245     Drawing::Brush brush;
246     canvas.AttachBrush(brush);
247     auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
248     auto gravityTranslate = GetGravityTranslate(cacheImage->GetWidth(), cacheImage->GetHeight());
249     canvas.DrawImage(*cacheImage, gravityTranslate.x_, gravityTranslate.y_, samplingOptions);
250     canvas.DetachBrush();
251     canvas.Restore();
252     return true;
253 }
254 
InitCacheSurface(Drawing::GPUContext * gpuContext,ClearCacheSurfaceFunc func,uint32_t threadIndex,bool isHdrOn)255 void RSSurfaceRenderNodeDrawable::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func,
256     uint32_t threadIndex, bool isHdrOn)
257 {
258     if (func) {
259         cacheSurfaceThreadIndex_ = threadIndex;
260         if (!clearCacheSurfaceFunc_) {
261             clearCacheSurfaceFunc_ = func;
262         }
263         if (cacheSurface_) {
264             func(std::move(cacheSurface_), nullptr,
265                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
266             cacheSurface_ = nullptr;
267         }
268     } else {
269         cacheSurface_ = nullptr;
270     }
271 
272     float width = 0.0f;
273     float height = 0.0f;
274     if (const auto& params = GetRenderParams()) {
275         auto size = params->GetCacheSize();
276         boundsWidth_ = size.x_;
277         boundsHeight_ = size.y_;
278     } else {
279         RS_LOGE("uifirst cannot get cachesize");
280     }
281 
282     width = boundsWidth_;
283     height = boundsHeight_;
284 
285 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
286     if (gpuContext == nullptr) {
287         if (func) {
288             std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
289             func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
290                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
291             ClearCacheSurface();
292         }
293         RS_LOGE("RSSurfaceRenderNodeDrawable::InitCacheSurface gpuContext == nullptr");
294         return;
295     }
296 #ifdef RS_ENABLE_GL
297     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
298         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
299         Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(width, height);
300         cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
301     }
302 #endif
303 #ifdef RS_ENABLE_VK
304     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
305         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
306         VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
307         auto colorType = Drawing::ColorType::COLORTYPE_RGBA_8888;
308         if (isHdrOn) {
309             format = VK_FORMAT_R16G16B16A16_SFLOAT;
310             colorType = Drawing::ColorType::COLORTYPE_RGBA_F16;
311         }
312         cacheBackendTexture_ = RSUniRenderUtil::MakeBackendTexture(width, height, format);
313         auto vkTextureInfo = cacheBackendTexture_.GetTextureInfo().GetVKTextureInfo();
314         if (!cacheBackendTexture_.IsValid() || !vkTextureInfo) {
315             if (func) {
316                 std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
317                 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
318                     cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
319                 ClearCacheSurface();
320             }
321             RS_LOGE("RSSurfaceRenderNodeDrawable::InitCacheSurface !cacheBackendTexture_.IsValid() || !vkTextureInfo");
322             return;
323         }
324         cacheCleanupHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
325             vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
326         cacheSurface_ = Drawing::Surface::MakeFromBackendTexture(
327             gpuContext, cacheBackendTexture_.GetTextureInfo(), Drawing::TextureOrigin::BOTTOM_LEFT,
328             1, colorType, nullptr,
329             NativeBufferUtils::DeleteVkImage, cacheCleanupHelper_);
330     }
331 #endif
332 #else
333     cacheSurface_ = Drawing::Surface::MakeRasterN32Premul(width, height);
334 #endif
335 }
HasCachedTexture() const336 bool RSSurfaceRenderNodeDrawable::HasCachedTexture() const
337 {
338 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
339     return isTextureValid_.load() || surfaceHandlerUiFirst_->GetBuffer() != nullptr;
340 #else
341     return true;
342 #endif
343 }
344 
NeedInitCacheSurface()345 bool RSSurfaceRenderNodeDrawable::NeedInitCacheSurface()
346 {
347     int width = 0;
348     int height = 0;
349 
350     if (const auto& params = GetRenderParams()) {
351         auto size = params->GetCacheSize();
352         width =  size.x_;
353         height = size.y_;
354     }
355 
356     if (cacheSurface_ == nullptr) {
357         return true;
358     }
359     auto cacheCanvas = cacheSurface_->GetCanvas();
360     if (cacheCanvas == nullptr) {
361         return true;
362     }
363     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
364 }
365 
366 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
UpdateBackendTexture()367 void RSSurfaceRenderNodeDrawable::UpdateBackendTexture()
368 {
369     RS_TRACE_NAME("RSRenderNodeDrawable::UpdateBackendTexture()");
370     if (cacheSurface_ == nullptr) {
371         return;
372     }
373     cacheBackendTexture_ = cacheSurface_->GetBackendTexture();
374 }
375 #endif
376 
UpdateCompletedCacheSurface()377 void RSSurfaceRenderNodeDrawable::UpdateCompletedCacheSurface()
378 {
379     RS_TRACE_NAME("RSRenderNodeDrawable::UpdateCompletedCacheSurface()");
380     // renderthread not use, subthread done not use
381     std::swap(cacheSurface_, cacheCompletedSurface_);
382     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
383 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
384     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
385 #ifdef RS_ENABLE_VK
386     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
387         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
388         std::swap(cacheCleanupHelper_, cacheCompletedCleanupHelper_);
389     }
390 #endif
391     SetTextureValidFlag(true);
392     SetCacheSurfaceNeedUpdated(false);
393 #endif
394     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheSurface_, "cacheSurface_");
395     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheCompletedSurface_, "cacheCompletedSurface_");
396 }
SetTextureValidFlag(bool isValid)397 void RSSurfaceRenderNodeDrawable::SetTextureValidFlag(bool isValid)
398 {
399 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
400     isTextureValid_.store(isValid);
401 #endif
402 }
ClearCacheSurface(bool isClearCompletedCacheSurface)403 void RSSurfaceRenderNodeDrawable::ClearCacheSurface(bool isClearCompletedCacheSurface)
404 {
405     cacheSurface_ = nullptr;
406 #ifdef RS_ENABLE_VK
407     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
408         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
409         cacheCleanupHelper_ = nullptr;
410     }
411 #endif
412     if (isClearCompletedCacheSurface) {
413         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
414         cacheCompletedSurface_ = nullptr;
415 #ifdef RS_ENABLE_VK
416         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
417             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
418             cacheCompletedCleanupHelper_ = nullptr;
419         }
420 #endif
421 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
422         isTextureValid_.store(false);
423 #endif
424     }
425 }
426 
IsCurFrameStatic(DeviceType deviceType)427 bool RSSurfaceRenderNodeDrawable::IsCurFrameStatic(DeviceType deviceType)
428 {
429     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
430     if (!surfaceParams) {
431         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw params is nullptr");
432         return false;
433     }
434     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::GetSurfaceCacheContentStatic: [%d] name [%s] Id:%" PRIu64 "",
435         surfaceParams->GetSurfaceCacheContentStatic(), surfaceParams->GetName().c_str(), surfaceParams->GetId());
436     return surfaceParams->GetSurfaceCacheContentStatic();
437 }
438 
SetTaskFrameCount(uint64_t frameCount)439 void RSSurfaceRenderNodeDrawable::SetTaskFrameCount(uint64_t frameCount)
440 {
441     frameCount_ = frameCount;
442 }
443 
GetTaskFrameCount() const444 uint64_t RSSurfaceRenderNodeDrawable::GetTaskFrameCount() const
445 {
446     return frameCount_;
447 }
448 
SubDraw(Drawing::Canvas & canvas)449 void RSSurfaceRenderNodeDrawable::SubDraw(Drawing::Canvas& canvas)
450 {
451     const auto& uifirstParams = GetUifirstRenderParams();
452     auto debugSize = uifirstParams ? uifirstParams->GetCacheSize() : Vector2f(0.f, 0.f);
453     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::SubDraw[%s] w%.1f h%.1f",
454         name_.c_str(), debugSize.x_, debugSize.y_);
455 
456     auto rscanvas = reinterpret_cast<RSPaintFilterCanvas*>(&canvas);
457     if (!rscanvas) {
458         RS_LOGE("RSSurfaceRenderNodeDrawable::SubDraw, rscanvas us nullptr");
459         return;
460     }
461     Drawing::Rect bounds = uifirstParams ? uifirstParams->GetBounds() : Drawing::Rect(0, 0, 0, 0);
462 
463     auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
464     RSRenderParams::SetParentSurfaceMatrix(IDENTITY_MATRIX);
465 
466     RSRenderNodeDrawable::DrawUifirstContentChildren(*rscanvas, bounds);
467     RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
468 }
469 
DrawUIFirstCache(RSPaintFilterCanvas & rscanvas,bool canSkipWait)470 bool RSSurfaceRenderNodeDrawable::DrawUIFirstCache(RSPaintFilterCanvas& rscanvas, bool canSkipWait)
471 {
472     RS_TRACE_NAME_FMT("DrawUIFirstCache_NOSTARTING");
473     const auto& params = GetRenderParams();
474     if (!params) {
475         RS_LOGE("RSUniRenderUtil::HandleSubThreadNodeDrawable params is nullptr");
476         return false;
477     }
478 
479     static constexpr int REQUEST_SET_FRAME_LOAD_ID = 100006;
480     static constexpr int REQUEST_FRAME_AWARE_LOAD = 90;
481     static constexpr int REQUEST_FRAME_STANDARD_LOAD = 50;
482     if (!HasCachedTexture()) {
483         RS_TRACE_NAME_FMT("HandleSubThreadNode wait %d %" PRIu64 "", canSkipWait, nodeId_);
484         if (canSkipWait) {
485             return false; // draw nothing
486         }
487 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
488         bool frameParamEnable = RsFrameReport::GetInstance().GetEnable();
489         if (frameParamEnable) {
490             RsFrameReport::GetInstance().SetFrameParam(
491                 REQUEST_SET_FRAME_LOAD_ID, REQUEST_FRAME_AWARE_LOAD, 0, GetLastFrameUsedThreadIndex());
492         }
493         RSSubThreadManager::Instance()->WaitNodeTask(nodeId_);
494         if (frameParamEnable) {
495             RsFrameReport::GetInstance().SetFrameParam(
496                 REQUEST_SET_FRAME_LOAD_ID, REQUEST_FRAME_STANDARD_LOAD, 0, GetLastFrameUsedThreadIndex());
497         }
498         UpdateCompletedCacheSurface();
499 #endif
500     }
501     return DrawCacheSurface(rscanvas, params->GetCacheSize(), UNI_MAIN_THREAD_INDEX, true);
502 }
503 
DrawUIFirstCacheWithStarting(RSPaintFilterCanvas & rscanvas,NodeId id)504 bool RSSurfaceRenderNodeDrawable::DrawUIFirstCacheWithStarting(RSPaintFilterCanvas& rscanvas, NodeId id)
505 {
506     RS_TRACE_NAME_FMT("DrawUIFirstCacheWithStarting %d, nodeID:%" PRIu64 "", HasCachedTexture(), id);
507     const auto& params = GetRenderParams();
508     if (!params) {
509         RS_LOGE("RSUniRenderUtil::HandleSubThreadNodeDrawable params is nullptr");
510         return false;
511     }
512     bool ret = true;
513     // draw surface content&&childrensss
514     if (HasCachedTexture()) {
515         ret = DrawCacheSurface(rscanvas, params->GetCacheSize(), UNI_MAIN_THREAD_INDEX, true);
516     }
517     // draw starting window
518     {
519         auto drawable = RSRenderNodeDrawableAdapter::GetDrawableById(id);
520         if (!drawable) {
521             return false;
522         }
523         RS_TRACE_NAME_FMT("drawStarting");
524         drawable->Draw(rscanvas);
525     }
526     return ret;
527 }
528 
SetSubThreadSkip(bool isSubThreadSkip)529 void RSSurfaceRenderNodeDrawable::SetSubThreadSkip(bool isSubThreadSkip)
530 {
531     isSubThreadSkip_ = isSubThreadSkip;
532 }
533 } // namespace OHOS::Rosen
534