• 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 "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 #ifdef RS_ENABLE_VK
49 namespace {
findMemoryType(uint32_t typeFilter,VkMemoryPropertyFlags properties)50 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
51 {
52     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
53     VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
54 
55     VkPhysicalDeviceMemoryProperties memProperties;
56     vkContext.vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
57 
58     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
59         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
60             return i;
61         }
62     }
63 
64     return UINT32_MAX;
65 }
66 
SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,const VkImageCreateInfo & imageInfo)67 void SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,
68     const VkImageCreateInfo& imageInfo)
69 {
70     vkImageInfo->imageTiling = imageInfo.tiling;
71     vkImageInfo->imageLayout = imageInfo.initialLayout;
72     vkImageInfo->format = imageInfo.format;
73     vkImageInfo->imageUsageFlags = imageInfo.usage;
74     vkImageInfo->levelCount = imageInfo.mipLevels;
75     vkImageInfo->currentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
76     vkImageInfo->ycbcrConversionInfo = {};
77     vkImageInfo->sharingMode = imageInfo.sharingMode;
78 }
79 
MakeBackendTexture(uint32_t width,uint32_t height,VkFormat format=VK_FORMAT_R8G8B8A8_UNORM)80 OHOS::Rosen::Drawing::BackendTexture MakeBackendTexture(uint32_t width, uint32_t height,
81     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM)
82 {
83     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
84     VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
85         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
86     VkImageCreateInfo imageInfo {
87         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
88         .pNext = nullptr,
89         .flags = 0,
90         .imageType = VK_IMAGE_TYPE_2D,
91         .format = format,
92         .extent = {width, height, 1},
93         .mipLevels = 1,
94         .arrayLayers = 1,
95         .samples = VK_SAMPLE_COUNT_1_BIT,
96         .tiling = tiling,
97         .usage = usage,
98         .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
99         .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
100     };
101 
102     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
103     VkDevice device = vkContext.GetDevice();
104     VkImage image = VK_NULL_HANDLE;
105     VkDeviceMemory memory = VK_NULL_HANDLE;
106 
107     if (width * height > VKIMAGE_LIMIT_SIZE) {
108         ROSEN_LOGE(
109             "RSUniRenderUtil::MakeBackendTexture failed, image is too large, width:%{public}u, height::%{public}u",
110             width, height);
111         return {};
112     }
113 
114     if (vkContext.vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
115         return {};
116     }
117 
118     VkMemoryRequirements memRequirements;
119     vkContext.vkGetImageMemoryRequirements(device, image, &memRequirements);
120 
121     VkMemoryAllocateInfo allocInfo{};
122     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
123     allocInfo.allocationSize = memRequirements.size;
124     allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
125     if (allocInfo.memoryTypeIndex == UINT32_MAX) {
126         return {};
127     }
128 
129     if (vkContext.vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
130         return {};
131     }
132 
133     vkContext.vkBindImageMemory(device, image, memory, 0);
134 
135     OHOS::Rosen::Drawing::BackendTexture backendTexture(true);
136     OHOS::Rosen::Drawing::TextureInfo textureInfo;
137     textureInfo.SetWidth(width);
138     textureInfo.SetHeight(height);
139 
140     std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo =
141         std::make_shared<OHOS::Rosen::Drawing::VKTextureInfo>();
142     vkImageInfo->vkImage = image;
143     vkImageInfo->vkAlloc.memory = memory;
144     vkImageInfo->vkAlloc.size = memRequirements.size;
145 
146     SetVkImageInfo(vkImageInfo, imageInfo);
147     textureInfo.SetVKTextureInfo(vkImageInfo);
148     backendTexture.SetTextureInfo(textureInfo);
149     return backendTexture;
150 }
151 } // un-named
152 #endif // RS_ENABLE_VK
153 
154 namespace {
__anon26cf6dab0302() 155 static const OHOS::Rosen::Drawing::Matrix IDENTITY_MATRIX = []() {
156     OHOS::Rosen::Drawing::Matrix matrix;
157     matrix.SetMatrix(1.0f, 0.0f, 0.0f,
158                      0.0f, 1.0f, 0.0f,
159                      0.0f, 0.0f, 1.0f);
160     return matrix;
161 }();
162 }
163 
164 namespace OHOS::Rosen::DrawableV2 {
GetCacheSurfaceProcessedStatus() const165 CacheProcessStatus RSSurfaceRenderNodeDrawable::GetCacheSurfaceProcessedStatus() const
166 {
167     return uiFirstParams.cacheProcessStatus_.load();
168 }
169 
SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)170 void RSSurfaceRenderNodeDrawable::SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)
171 {
172     uiFirstParams.cacheProcessStatus_.store(cacheProcessStatus);
173     if (cacheProcessStatus == CacheProcessStatus::DONE || cacheProcessStatus == CacheProcessStatus::SKIPPED) {
174         RSUiFirstProcessStateCheckerHelper::NotifyAll();
175     }
176 }
177 
GetCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)178 std::shared_ptr<Drawing::Surface> RSSurfaceRenderNodeDrawable::GetCacheSurface(uint32_t threadIndex,
179     bool needCheckThread, bool releaseAfterGet)
180 {
181     {
182         if (releaseAfterGet) {
183             return std::move(cacheSurface_);
184         }
185         if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
186             return cacheSurface_;
187         }
188     }
189 
190     // freeze cache scene
191     ClearCacheSurfaceInThread();
192     return nullptr;
193 }
194 
ClearCacheSurfaceInThread()195 void RSSurfaceRenderNodeDrawable::ClearCacheSurfaceInThread()
196 {
197     if (UseDmaBuffer()) {
198         ClearBufferQueue();
199     } else {
200         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
201         if (clearCacheSurfaceFunc_) {
202             clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
203                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
204         }
205         ClearCacheSurface();
206     }
207 }
208 
ClearCacheSurfaceOnly()209 void RSSurfaceRenderNodeDrawable::ClearCacheSurfaceOnly()
210 {
211     RS_TRACE_NAME("ClearCacheSurfaceOnly");
212     if (cacheSurface_ == nullptr) {
213         return;
214     }
215     if (clearCacheSurfaceFunc_) {
216         clearCacheSurfaceFunc_(
217             std::move(cacheSurface_), nullptr, cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
218     }
219     ClearCacheSurface(false);
220     cacheSurface_.reset();
221 }
222 
GetGravityTranslate(float imgWidth,float imgHeight)223 Vector2f RSSurfaceRenderNodeDrawable::GetGravityTranslate(float imgWidth, float imgHeight)
224 {
225     auto surfaceParams = GetRenderParams() ?
226         static_cast<RSSurfaceRenderParams*>(GetRenderParams().get()) : nullptr;
227     if (!surfaceParams) {
228         RS_LOGE("RSSurfaceRenderNodeDrawable::GetGravityTranslate surfaceParams is nullptr");
229         return Vector2f{};
230     }
231     auto gravity = surfaceParams->GetUIFirstFrameGravity();
232     float boundsWidth = surfaceParams->GetCacheSize().x_;
233     float boundsHeight = surfaceParams->GetCacheSize().y_;
234     Drawing::Matrix gravityMatrix;
235     RSPropertiesPainter::GetGravityMatrix(gravity, RectF {0.0f, 0.0f, boundsWidth, boundsHeight},
236         imgWidth, imgHeight, gravityMatrix);
237     return {gravityMatrix.Get(Drawing::Matrix::TRANS_X), gravityMatrix.Get(Drawing::Matrix::TRANS_Y)};
238 }
239 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)240 std::shared_ptr<Drawing::Image> RSSurfaceRenderNodeDrawable::GetCompletedImage(
241     RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
242 {
243     auto gpuContext = canvas.GetGPUContext();
244     if (!gpuContext) {
245         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage GetGPUContext nullptr");
246         return nullptr;
247     }
248     if (isUIFirst) {
249 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
250         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
251         if (!cacheCompletedBackendTexture_.IsValid()) {
252             RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage invalid grBackendTexture_");
253             return nullptr;
254         }
255         auto colorType = Drawing::COLORTYPE_RGBA_8888;
256 #ifdef RS_ENABLE_VK
257         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
258             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
259             if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
260                 RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage surface %p cleanupHelper %p",
261                     cacheCompletedSurface_.get(), cacheCompletedSurface_.get());
262                 return nullptr;
263             }
264         }
265         auto vkTexture = cacheCompletedBackendTexture_.GetTextureInfo().GetVKTextureInfo();
266         if (vkTexture != nullptr && vkTexture->format == VK_FORMAT_R16G16B16A16_SFLOAT) {
267             colorType = Drawing::ColorType::COLORTYPE_RGBA_F16;
268         }
269 #endif
270         auto image = std::make_shared<Drawing::Image>();
271         Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
272         Drawing::BitmapFormat info = Drawing::BitmapFormat{ colorType,
273             Drawing::ALPHATYPE_PREMUL };
274 #ifdef RS_ENABLE_GL
275         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
276             OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
277             image->BuildFromTexture(*gpuContext, cacheCompletedBackendTexture_.GetTextureInfo(),
278                 origin, info, nullptr);
279         }
280 #endif
281 
282 #ifdef RS_ENABLE_VK
283         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
284             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
285             image->BuildFromTexture(*gpuContext, cacheCompletedBackendTexture_.GetTextureInfo(),
286                 origin, info, nullptr,
287                 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
288         }
289 #endif
290         return image;
291 #endif
292     }
293 
294     if (!cacheCompletedSurface_) {
295         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface invalid cacheCompletedSurface");
296         return nullptr;
297     }
298     auto completeImage = cacheCompletedSurface_->GetImageSnapshot();
299     if (!completeImage) {
300         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface Get complete image failed");
301         return nullptr;
302     }
303     if (threadIndex == completedSurfaceThreadIndex_) {
304         return completeImage;
305     }
306 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
307     Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
308     auto backendTexture = completeImage->GetBackendTexture(false, &origin);
309     if (!backendTexture.IsValid()) {
310         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage DrawCacheSurface get backendTexture failed");
311         return nullptr;
312     }
313     SharedTextureContext* sharedContext = new SharedTextureContext(completeImage);
314     auto cacheImage = std::make_shared<Drawing::Image>();
315     Drawing::BitmapFormat info =
316         Drawing::BitmapFormat{ completeImage->GetColorType(), completeImage->GetAlphaType() };
317     bool ret = cacheImage->BuildFromTexture(*gpuContext, backendTexture.GetTextureInfo(),
318         origin, info, nullptr, SKResourceManager::DeleteSharedTextureContext, sharedContext);
319     if (!ret) {
320         RS_LOGE("RSSurfaceRenderNodeDrawable::GetCompletedImage image BuildFromTexture failed");
321         return nullptr;
322     }
323     return cacheImage;
324 #else
325     return completeImage;
326 #endif
327 }
328 
DrawCacheSurface(RSPaintFilterCanvas & canvas,const Vector2f & boundSize,uint32_t threadIndex,bool isUIFirst)329 bool RSSurfaceRenderNodeDrawable::DrawCacheSurface(RSPaintFilterCanvas& canvas, const Vector2f& boundSize,
330     uint32_t threadIndex, bool isUIFirst)
331 {
332     if (ROSEN_EQ(boundsWidth_, 0.f) || ROSEN_EQ(boundsHeight_, 0.f)) {
333         RS_LOGE("RSSurfaceRenderNodeDrawable::DrawCacheSurface return %d", __LINE__);
334         return false;
335     }
336 
337     auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
338     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheImage, "cacheImage");
339     if (cacheImage == nullptr) {
340         RS_LOGE("RSSurfaceRenderNodeDrawable::DrawCacheSurface return %d", __LINE__);
341         return false;
342     }
343     float scaleX = boundSize.x_ / static_cast<float>(cacheImage->GetWidth());
344     float scaleY = boundSize.y_ / static_cast<float>(cacheImage->GetHeight());
345     canvas.Save();
346     canvas.Scale(scaleX, scaleY);
347     if (RSSystemProperties::GetRecordingEnabled()) {
348         if (cacheImage->IsTextureBacked()) {
349             RS_LOGI("RSSurfaceRenderNodeDrawable::DrawCacheSurface convert cacheImage from texture to raster image");
350             cacheImage = cacheImage->MakeRasterImage();
351         }
352     }
353     Drawing::Brush brush;
354     canvas.AttachBrush(brush);
355     auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
356     auto gravityTranslate = GetGravityTranslate(cacheImage->GetWidth(), cacheImage->GetHeight());
357     canvas.DrawImage(*cacheImage, gravityTranslate.x_, gravityTranslate.y_, samplingOptions);
358     canvas.DetachBrush();
359     canvas.Restore();
360     return true;
361 }
362 
InitCacheSurface(Drawing::GPUContext * gpuContext,ClearCacheSurfaceFunc func,uint32_t threadIndex,bool isHdrOn)363 void RSSurfaceRenderNodeDrawable::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func,
364     uint32_t threadIndex, bool isHdrOn)
365 {
366     if (func) {
367         cacheSurfaceThreadIndex_ = threadIndex;
368         if (!clearCacheSurfaceFunc_) {
369             clearCacheSurfaceFunc_ = func;
370         }
371         if (cacheSurface_) {
372             func(std::move(cacheSurface_), nullptr,
373                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
374             cacheSurface_ = nullptr;
375         }
376     } else {
377         cacheSurface_ = nullptr;
378     }
379 
380     float width = 0.0f;
381     float height = 0.0f;
382     if (const auto& params = GetRenderParams()) {
383         auto size = params->GetCacheSize();
384         boundsWidth_ = size.x_;
385         boundsHeight_ = size.y_;
386     } else {
387         RS_LOGE("uifirst cannot get cachesize");
388     }
389 
390     width = boundsWidth_;
391     height = boundsHeight_;
392 
393 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
394     if (gpuContext == nullptr) {
395         if (func) {
396             std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
397             func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
398                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
399             ClearCacheSurface();
400         }
401         RS_LOGE("RSSurfaceRenderNodeDrawable::InitCacheSurface gpuContext == nullptr");
402         return;
403     }
404 #ifdef RS_ENABLE_GL
405     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
406         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
407         Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(width, height);
408         cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
409     }
410 #endif
411 #ifdef RS_ENABLE_VK
412     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
413         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
414         VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
415         auto colorType = Drawing::ColorType::COLORTYPE_RGBA_8888;
416         if (isHdrOn) {
417             format = VK_FORMAT_R16G16B16A16_SFLOAT;
418             colorType = Drawing::ColorType::COLORTYPE_RGBA_F16;
419         }
420         cacheBackendTexture_ = MakeBackendTexture(width, height, format);
421         auto vkTextureInfo = cacheBackendTexture_.GetTextureInfo().GetVKTextureInfo();
422         if (!cacheBackendTexture_.IsValid() || !vkTextureInfo) {
423             if (func) {
424                 std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
425                 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
426                     cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
427                 ClearCacheSurface();
428             }
429             RS_LOGE("RSSurfaceRenderNodeDrawable::InitCacheSurface !cacheBackendTexture_.IsValid() || !vkTextureInfo");
430             return;
431         }
432         cacheCleanupHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
433             vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
434         cacheSurface_ = Drawing::Surface::MakeFromBackendTexture(
435             gpuContext, cacheBackendTexture_.GetTextureInfo(), Drawing::TextureOrigin::BOTTOM_LEFT,
436             1, colorType, nullptr,
437             NativeBufferUtils::DeleteVkImage, cacheCleanupHelper_);
438     }
439 #endif
440 #else
441     cacheSurface_ = Drawing::Surface::MakeRasterN32Premul(width, height);
442 #endif
443 }
HasCachedTexture() const444 bool RSSurfaceRenderNodeDrawable::HasCachedTexture() const
445 {
446 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
447     return isTextureValid_.load() || surfaceHandlerUiFirst_->GetBuffer() != nullptr;
448 #else
449     return true;
450 #endif
451 }
452 
NeedInitCacheSurface()453 bool RSSurfaceRenderNodeDrawable::NeedInitCacheSurface()
454 {
455     int width = 0;
456     int height = 0;
457 
458     if (const auto& params = GetRenderParams()) {
459         auto size = params->GetCacheSize();
460         width =  size.x_;
461         height = size.y_;
462     }
463 
464     if (cacheSurface_ == nullptr) {
465         return true;
466     }
467     auto cacheCanvas = cacheSurface_->GetCanvas();
468     if (cacheCanvas == nullptr) {
469         return true;
470     }
471     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
472 }
473 
474 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
UpdateBackendTexture()475 void RSSurfaceRenderNodeDrawable::UpdateBackendTexture()
476 {
477     RS_TRACE_NAME("RSRenderNodeDrawable::UpdateBackendTexture()");
478     if (cacheSurface_ == nullptr) {
479         return;
480     }
481     cacheBackendTexture_ = cacheSurface_->GetBackendTexture();
482 }
483 #endif
484 
UpdateCompletedCacheSurface()485 void RSSurfaceRenderNodeDrawable::UpdateCompletedCacheSurface()
486 {
487     RS_TRACE_NAME("RSRenderNodeDrawable::UpdateCompletedCacheSurface()");
488     // renderthread not use, subthread done not use
489     std::swap(cacheSurface_, cacheCompletedSurface_);
490     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
491 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
492     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
493 #ifdef RS_ENABLE_VK
494     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
495         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
496         std::swap(cacheCleanupHelper_, cacheCompletedCleanupHelper_);
497     }
498 #endif
499     SetTextureValidFlag(true);
500     SetCacheSurfaceNeedUpdated(false);
501 #endif
502     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheSurface_, "cacheSurface_");
503     RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(cacheCompletedSurface_, "cacheCompletedSurface_");
504 }
SetTextureValidFlag(bool isValid)505 void RSSurfaceRenderNodeDrawable::SetTextureValidFlag(bool isValid)
506 {
507 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
508     isTextureValid_.store(isValid);
509 #endif
510 }
ClearCacheSurface(bool isClearCompletedCacheSurface)511 void RSSurfaceRenderNodeDrawable::ClearCacheSurface(bool isClearCompletedCacheSurface)
512 {
513     cacheSurface_ = nullptr;
514 #ifdef RS_ENABLE_VK
515     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
516         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
517         cacheCleanupHelper_ = nullptr;
518     }
519 #endif
520     if (isClearCompletedCacheSurface) {
521         std::scoped_lock<std::recursive_mutex> lock(completeResourceMutex_);
522         cacheCompletedSurface_ = nullptr;
523 #ifdef RS_ENABLE_VK
524         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
525             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
526             cacheCompletedCleanupHelper_ = nullptr;
527         }
528 #endif
529 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
530         isTextureValid_.store(false);
531 #endif
532     }
533 }
534 
IsCurFrameStatic(DeviceType deviceType)535 bool RSSurfaceRenderNodeDrawable::IsCurFrameStatic(DeviceType deviceType)
536 {
537     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
538     if (!surfaceParams) {
539         RS_LOGE("RSSurfaceRenderNodeDrawable::OnDraw params is nullptr");
540         return false;
541     }
542     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::GetSurfaceCacheContentStatic: [%d] name [%s] Id:%" PRIu64 "",
543         surfaceParams->GetSurfaceCacheContentStatic(), surfaceParams->GetName().c_str(), surfaceParams->GetId());
544     return surfaceParams->GetSurfaceCacheContentStatic();
545 }
546 
SetTaskFrameCount(uint64_t frameCount)547 void RSSurfaceRenderNodeDrawable::SetTaskFrameCount(uint64_t frameCount)
548 {
549     frameCount_ = frameCount;
550 }
551 
GetTaskFrameCount() const552 uint64_t RSSurfaceRenderNodeDrawable::GetTaskFrameCount() const
553 {
554     return frameCount_;
555 }
556 
SubDraw(Drawing::Canvas & canvas)557 void RSSurfaceRenderNodeDrawable::SubDraw(Drawing::Canvas& canvas)
558 {
559     const auto& uifirstParams = GetUifirstRenderParams();
560     auto debugSize = uifirstParams ? uifirstParams->GetCacheSize() : Vector2f(0.f, 0.f);
561     RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::SubDraw[%s] w%.1f h%.1f",
562         name_.c_str(), debugSize.x_, debugSize.y_);
563 
564     auto rscanvas = reinterpret_cast<RSPaintFilterCanvas*>(&canvas);
565     if (!rscanvas) {
566         RS_LOGE("RSSurfaceRenderNodeDrawable::SubDraw, rscanvas us nullptr");
567         return;
568     }
569     Drawing::Rect bounds = uifirstParams ? uifirstParams->GetBounds() : Drawing::Rect(0, 0, 0, 0);
570 
571     auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
572     RSRenderParams::SetParentSurfaceMatrix(IDENTITY_MATRIX);
573 
574     RSRenderNodeDrawable::DrawUifirstContentChildren(*rscanvas, bounds);
575     RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
576 }
577 
DrawUIFirstCache(RSPaintFilterCanvas & rscanvas,bool canSkipWait)578 bool RSSurfaceRenderNodeDrawable::DrawUIFirstCache(RSPaintFilterCanvas& rscanvas, bool canSkipWait)
579 {
580     RS_TRACE_NAME_FMT("DrawUIFirstCache_NOSTARTING");
581     const auto& params = GetRenderParams();
582     if (!params) {
583         RS_LOGE("RSUniRenderUtil::HandleSubThreadNodeDrawable params is nullptr");
584         return false;
585     }
586 
587     static constexpr int REQUEST_SET_FRAME_LOAD_ID = 100006;
588     static constexpr int REQUEST_FRAME_AWARE_LOAD = 90;
589     static constexpr int REQUEST_FRAME_STANDARD_LOAD = 50;
590     if (!HasCachedTexture()) {
591         RS_TRACE_NAME_FMT("HandleSubThreadNode wait %d %lld", canSkipWait, nodeId_);
592         if (canSkipWait) {
593             return false; // draw nothing
594         }
595 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
596         bool frameParamEnable = RsFrameReport::GetInstance().GetEnable();
597         if (frameParamEnable) {
598             RsFrameReport::GetInstance().SetFrameParam(
599                 REQUEST_SET_FRAME_LOAD_ID, REQUEST_FRAME_AWARE_LOAD, 0, GetLastFrameUsedThreadIndex());
600         }
601         RSSubThreadManager::Instance()->WaitNodeTask(nodeId_);
602         if (frameParamEnable) {
603             RsFrameReport::GetInstance().SetFrameParam(
604                 REQUEST_SET_FRAME_LOAD_ID, REQUEST_FRAME_STANDARD_LOAD, 0, GetLastFrameUsedThreadIndex());
605         }
606         UpdateCompletedCacheSurface();
607 #endif
608     }
609     return DrawCacheSurface(rscanvas, params->GetCacheSize(), UNI_MAIN_THREAD_INDEX, true);
610 }
611 
DrawUIFirstCacheWithStarting(RSPaintFilterCanvas & rscanvas,NodeId id)612 bool RSSurfaceRenderNodeDrawable::DrawUIFirstCacheWithStarting(RSPaintFilterCanvas& rscanvas, NodeId id)
613 {
614     RS_TRACE_NAME_FMT("DrawUIFirstCacheWithStarting %d, nodeID:%lld", HasCachedTexture(), id);
615     const auto& params = GetRenderParams();
616     if (!params) {
617         RS_LOGE("RSUniRenderUtil::HandleSubThreadNodeDrawable params is nullptr");
618         return false;
619     }
620     bool ret = true;
621     // draw surface content&&childrensss
622     if (HasCachedTexture()) {
623         ret = DrawCacheSurface(rscanvas, params->GetCacheSize(), UNI_MAIN_THREAD_INDEX, true);
624     }
625     // draw starting window
626     {
627         auto drawable = RSRenderNodeDrawableAdapter::GetDrawableById(id);
628         if (!drawable) {
629             return false;
630         }
631         RS_TRACE_NAME_FMT("drawStarting");
632         drawable->Draw(rscanvas);
633     }
634     return ret;
635 }
636 
SetSubThreadSkip(bool isSubThreadSkip)637 void RSSurfaceRenderNodeDrawable::SetSubThreadSkip(bool isSubThreadSkip)
638 {
639     isSubThreadSkip_ = isSubThreadSkip;
640 }
641 } // namespace OHOS::Rosen
642