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