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