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