1 /*
2 * Copyright (c) 2021-2023 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 "pipeline/rs_surface_render_node.h"
17
18 #ifndef USE_ROSEN_DRAWING
19 #include "include/core/SkMatrix.h"
20 #include "include/core/SkRect.h"
21 #include "rs_trace.h"
22 #ifdef NEW_SKIA
23 #include "include/gpu/GrDirectContext.h"
24 #else
25 #include "include/gpu/GrContext.h"
26 #endif
27 #endif
28
29 #include "command/rs_surface_node_command.h"
30 #include "common/rs_common_def.h"
31 #include "rs_trace.h"
32 #include "common/rs_optional_trace.h"
33 #include "common/rs_obj_abs_geometry.h"
34 #include "common/rs_rect.h"
35 #include "common/rs_vector2.h"
36 #include "common/rs_vector4.h"
37 #include "ipc_callbacks/rs_rt_refresh_callback.h"
38 #include "pipeline/rs_render_node.h"
39 #include "pipeline/rs_effect_render_node.h"
40 #include "pipeline/rs_root_render_node.h"
41 #include "platform/common/rs_log.h"
42 #include "platform/ohos/rs_jank_stats.h"
43 #include "property/rs_properties_painter.h"
44 #include "render/rs_skia_filter.h"
45 #include "transaction/rs_render_service_client.h"
46 #include "visitor/rs_node_visitor.h"
47 #include "property/rs_property_drawable.h"
48
49 namespace OHOS {
50 namespace Rosen {
51 const int SCB_NODE_NAME_PREFIX_LENGTH = 3;
RSSurfaceRenderNode(const RSSurfaceRenderNodeConfig & config,const std::weak_ptr<RSContext> & context)52 RSSurfaceRenderNode::RSSurfaceRenderNode(
53 const RSSurfaceRenderNodeConfig& config, const std::weak_ptr<RSContext>& context)
54 : RSRenderNode(config.id, context, config.isTextureExportNode), RSSurfaceHandler(config.id), name_(config.name),
55 bundleName_(config.bundleName), nodeType_(config.nodeType),
56 dirtyManager_(std::make_shared<RSDirtyRegionManager>()),
57 cacheSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
58 {
59 #ifndef ROSEN_ARKUI_X
60 MemoryInfo info = {sizeof(*this), ExtractPid(config.id), config.id, MEMORY_TYPE::MEM_RENDER_NODE};
61 MemoryTrack::Instance().AddNodeRecord(config.id, info);
62 #endif
63 }
64
RSSurfaceRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)65 RSSurfaceRenderNode::RSSurfaceRenderNode(NodeId id, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
66 : RSSurfaceRenderNode(RSSurfaceRenderNodeConfig { .id = id, .name = "SurfaceNode",
67 .isTextureExportNode = isTextureExportNode}, context)
68 {}
69
~RSSurfaceRenderNode()70 RSSurfaceRenderNode::~RSSurfaceRenderNode()
71 {
72 #ifdef USE_SURFACE_TEXTURE
73 SetSurfaceTexture(nullptr);
74 #endif
75 #ifndef ROSEN_ARKUI_X
76 MemoryTrack::Instance().RemoveNodeRecord(GetId());
77 #endif
78 }
79
80 #ifndef ROSEN_CROSS_PLATFORM
SetConsumer(const sptr<IConsumerSurface> & consumer)81 void RSSurfaceRenderNode::SetConsumer(const sptr<IConsumerSurface>& consumer)
82 {
83 consumer_ = consumer;
84 }
85 #endif
86
87 #ifndef USE_ROSEN_DRAWING
UpdateSrcRect(const RSPaintFilterCanvas & canvas,const SkIRect & dstRect,bool hasRotation)88 void RSSurfaceRenderNode::UpdateSrcRect(const RSPaintFilterCanvas& canvas, const SkIRect& dstRect, bool hasRotation)
89 {
90 auto localClipRect = RSPaintFilterCanvas::GetLocalClipBounds(canvas, &dstRect).value_or(SkRect::MakeEmpty());
91 const RSProperties& properties = GetRenderProperties();
92 int left = std::clamp<int>(localClipRect.left(), 0, properties.GetBoundsWidth());
93 int top = std::clamp<int>(localClipRect.top(), 0, properties.GetBoundsHeight());
94 int width = std::clamp<int>(std::ceil(localClipRect.width()), 0, std::ceil(properties.GetBoundsWidth() - left));
95 int height = std::clamp<int>(std::ceil(localClipRect.height()), 0, std::ceil(properties.GetBoundsHeight() - top));
96 RectI srcRect = {left, top, width, height};
97 SetSrcRect(srcRect);
98 }
99 #else
UpdateSrcRect(const RSPaintFilterCanvas & canvas,const Drawing::RectI & dstRect,bool hasRotation)100 void RSSurfaceRenderNode::UpdateSrcRect(const RSPaintFilterCanvas& canvas, const Drawing::RectI& dstRect,
101 bool hasRotation)
102 {
103 auto localClipRect = RSPaintFilterCanvas::GetLocalClipBounds(canvas, &dstRect).value_or(Drawing::Rect());
104 const RSProperties& properties = GetRenderProperties();
105 int left = std::clamp<int>(localClipRect.GetLeft(), 0, properties.GetBoundsWidth());
106 int top = std::clamp<int>(localClipRect.GetTop(), 0, properties.GetBoundsHeight());
107 int width = std::clamp<int>(std::ceil(localClipRect.GetWidth()), 0,
108 std::ceil(properties.GetBoundsWidth() - left));
109 int height = std::clamp<int>(std::ceil(localClipRect.GetHeight()), 0,
110 std::ceil(properties.GetBoundsHeight() - top));
111 RectI srcRect = {left, top, width, height};
112 SetSrcRect(srcRect);
113 // We allow 1px error value to avoid disable dss by mistake [this flag only used for YUV buffer format]
114 if (IsYUVBufferFormat()) {
115 isHardwareForcedDisabledBySrcRect_ = hasRotation ?
116 (width + 1 < static_cast<int>(properties.GetBoundsWidth())) :
117 (height + 1 < static_cast<int>(properties.GetBoundsHeight()));
118 #ifndef ROSEN_CROSS_PLATFORM
119 RS_OPTIONAL_TRACE_NAME_FMT("UpdateSrcRect hwcDisableBySrc:%d localClip:[%.2f, %.2f, %.2f, %.2f]" \
120 " bounds:[%.2f, %.2f] hasRotation:%d name:%s id:%llu",
121 isHardwareForcedDisabledBySrcRect_,
122 localClipRect.GetLeft(), localClipRect.GetTop(), localClipRect.GetWidth(), localClipRect.GetHeight(),
123 properties.GetBoundsWidth(), properties.GetBoundsHeight(), hasRotation,
124 GetName().c_str(), GetId());
125 #endif
126 }
127 }
128 #endif
129
IsHardwareDisabledBySrcRect() const130 bool RSSurfaceRenderNode::IsHardwareDisabledBySrcRect() const
131 {
132 return isHardwareForcedDisabledBySrcRect_;
133 }
134
IsYUVBufferFormat() const135 bool RSSurfaceRenderNode::IsYUVBufferFormat() const
136 {
137 #ifndef ROSEN_CROSS_PLATFORM
138 if (GetBuffer() == nullptr) {
139 return false;
140 }
141 auto format = GetBuffer()->GetFormat();
142 if (format < GRAPHIC_PIXEL_FMT_YUV_422_I || format == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
143 format > GRAPHIC_PIXEL_FMT_YCRCB_P010) {
144 return false;
145 }
146 return true;
147 #else
148 return false;
149 #endif
150 }
151
ShouldPrepareSubnodes()152 bool RSSurfaceRenderNode::ShouldPrepareSubnodes()
153 {
154 // if a appwindow or abilitycomponent has a empty dstrect, its subnodes' prepare stage can be skipped
155 // most common scenario: HiBoard (SwipeLeft screen on home screen)
156 if (GetDstRect().IsEmpty() && (IsAppWindow() || IsAbilityComponent())) {
157 return false;
158 }
159 return true;
160 }
161
StoreMustRenewedInfo()162 void RSSurfaceRenderNode::StoreMustRenewedInfo()
163 {
164 mustRenewedInfo_ = RSRenderNode::HasMustRenewedInfo() || hasSecurityLayer_ || hasSkipLayer_;
165 }
166
DirtyRegionDump() const167 std::string RSSurfaceRenderNode::DirtyRegionDump() const
168 {
169 std::string dump = GetName() +
170 " SurfaceNodeType [" + std::to_string(static_cast<unsigned int>(GetSurfaceNodeType())) + "]" +
171 " Transparent [" + std::to_string(IsTransparent()) +"]" +
172 " DstRect: " + GetDstRect().ToString() +
173 " VisibleRegion: " + GetVisibleRegion().GetRegionInfo() +
174 " VisibleDirtyRegion: " + GetVisibleDirtyRegion().GetRegionInfo() +
175 " GlobalDirtyRegion: " + GetGlobalDirtyRegion().GetRegionInfo();
176 if (GetDirtyManager()) {
177 dump += " DirtyRegion: " + GetDirtyManager()->GetDirtyRegion().ToString();
178 }
179 return dump;
180 }
181
PrepareRenderBeforeChildren(RSPaintFilterCanvas & canvas)182 void RSSurfaceRenderNode::PrepareRenderBeforeChildren(RSPaintFilterCanvas& canvas)
183 {
184 // Save the current state of the canvas before modifying it.
185 #ifndef USE_ROSEN_DRAWING
186 renderNodeSaveCount_ = canvas.Save();
187 #else
188 renderNodeSaveCount_ = canvas.SaveAllStatus();
189 #endif
190
191 // Apply alpha to canvas
192 const RSProperties& properties = GetRenderProperties();
193 canvas.MultiplyAlpha(properties.GetAlpha());
194
195 // Apply matrix to canvas
196 auto currentGeoPtr = (properties.GetBoundsGeometry());
197 if (currentGeoPtr != nullptr) {
198 currentGeoPtr->UpdateByMatrixFromSelf();
199 auto matrix = currentGeoPtr->GetMatrix();
200 #ifndef USE_ROSEN_DRAWING
201 matrix.setTranslateX(std::ceil(matrix.getTranslateX()));
202 matrix.setTranslateY(std::ceil(matrix.getTranslateY()));
203 canvas.concat(matrix);
204 #else
205 matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X)));
206 matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y)));
207 canvas.ConcatMatrix(matrix);
208 #endif
209 }
210
211 // Clip by bounds
212 #ifndef USE_ROSEN_DRAWING
213 canvas.clipRect(SkRect::MakeWH(std::floor(properties.GetBoundsWidth()), std::floor(properties.GetBoundsHeight())));
214
215 // Extract srcDest and dstRect from SkCanvas, localCLipBounds as SrcRect, deviceClipBounds as DstRect
216 auto deviceClipRect = canvas.getDeviceClipBounds();
217 UpdateSrcRect(canvas, deviceClipRect);
218 RectI dstRect = { deviceClipRect.left(), deviceClipRect.top(), deviceClipRect.width(), deviceClipRect.height() };
219 SetDstRect(dstRect);
220
221 // Save TotalMatrix and GlobalAlpha for compositor
222 SetTotalMatrix(canvas.getTotalMatrix());
223 #else
224 canvas.ClipRect(Drawing::Rect(0, 0, std::floor(properties.GetBoundsWidth()),
225 std::floor(properties.GetBoundsHeight())), Drawing::ClipOp::INTERSECT, false);
226
227 // Extract srcDest and dstRect from Drawing::Canvas, localCLipBounds as SrcRect, deviceClipBounds as DstRect
228 auto deviceClipRect = canvas.GetDeviceClipBounds();
229 UpdateSrcRect(canvas, deviceClipRect);
230 RectI dstRect = {
231 deviceClipRect.GetLeft(), deviceClipRect.GetTop(), deviceClipRect.GetWidth(), deviceClipRect.GetHeight() };
232 SetDstRect(dstRect);
233
234 // Save TotalMatrix and GlobalAlpha for compositor
235 SetTotalMatrix(canvas.GetTotalMatrix());
236 #endif
237 SetGlobalAlpha(canvas.GetAlpha());
238 }
239
PrepareRenderAfterChildren(RSPaintFilterCanvas & canvas)240 void RSSurfaceRenderNode::PrepareRenderAfterChildren(RSPaintFilterCanvas& canvas)
241 {
242 canvas.RestoreStatus(renderNodeSaveCount_);
243 }
244
CollectSurface(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<RSBaseRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)245 void RSSurfaceRenderNode::CollectSurface(const std::shared_ptr<RSBaseRenderNode>& node,
246 std::vector<RSBaseRenderNode::SharedPtr>& vec, bool isUniRender, bool onlyFirstLevel)
247 {
248 if (IsScbScreen()) {
249 for (auto& child : *node->GetSortedChildren()) {
250 child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
251 }
252 return;
253 }
254 if (IsStartingWindow()) {
255 if (isUniRender) {
256 vec.emplace_back(shared_from_this());
257 }
258 return;
259 }
260 if (IsLeashWindow()) {
261 if (isUniRender) {
262 vec.emplace_back(shared_from_this());
263 }
264 if (onlyFirstLevel) {
265 return;
266 }
267 for (auto& child : *node->GetSortedChildren()) {
268 child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
269 }
270 return;
271 }
272
273 #ifndef ROSEN_CROSS_PLATFORM
274 auto& consumer = GetConsumer();
275 if (consumer != nullptr && consumer->GetTunnelHandle() != nullptr) {
276 return;
277 }
278 #endif
279 auto num = find(vec.begin(), vec.end(), shared_from_this());
280 if (num != vec.end()) {
281 return;
282 }
283 if (isUniRender && ShouldPaint()) {
284 vec.emplace_back(shared_from_this());
285 } else {
286 #ifndef ROSEN_CROSS_PLATFORM
287 if (GetBuffer() != nullptr && ShouldPaint()) {
288 vec.emplace_back(shared_from_this());
289 }
290 #endif
291 }
292
293 if (isSubSurfaceEnabled_) {
294 if (onlyFirstLevel) {
295 return;
296 }
297 for (auto &nodes : node->GetSubSurfaceNodes()) {
298 for (auto &node : nodes.second) {
299 auto surfaceNode = node.lock();
300 if (surfaceNode != nullptr) {
301 surfaceNode->CollectSurface(surfaceNode, vec, isUniRender, onlyFirstLevel);
302 }
303 }
304 }
305 }
306 }
307
CollectSurfaceForUIFirstSwitch(uint32_t & leashWindowCount,uint32_t minNodeNum)308 void RSSurfaceRenderNode::CollectSurfaceForUIFirstSwitch(uint32_t& leashWindowCount, uint32_t minNodeNum)
309 {
310 if (IsLeashWindow() || IsStartingWindow()) {
311 leashWindowCount++;
312 }
313 return;
314 }
315
ClearChildrenCache()316 void RSSurfaceRenderNode::ClearChildrenCache()
317 {
318 for (auto& child : *GetChildren()) {
319 auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>();
320 if (surfaceNode == nullptr) {
321 continue;
322 }
323 #ifndef ROSEN_CROSS_PLATFORM
324 auto& consumer = surfaceNode->GetConsumer();
325 if (consumer != nullptr) {
326 consumer->GoBackground();
327 }
328 #endif
329 }
330 // Temporary solution, GetChildren will generate fullChildrenList_, which will cause memory leak
331 OnTreeStateChanged();
332 }
333
OnTreeStateChanged()334 void RSSurfaceRenderNode::OnTreeStateChanged()
335 {
336 RSRenderNode::OnTreeStateChanged();
337 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
338 if (grContext_ && !IsOnTheTree()) {
339 if (auto context = GetContext().lock()) {
340 RS_TRACE_NAME_FMT("need purgeUnlockedResources this SurfaceNode isn't on the tree Id:%" PRIu64 " Name:%s",
341 GetId(), GetName().c_str());
342 RS_LOGD("need purgeUnlockedResources this SurfaceNode isn't on the tree Id:%" PRIu64 " Name:%s",
343 GetId(), GetName().c_str());
344 if (IsLeashWindow()) {
345 context->MarkNeedPurge(ClearMemoryMoment::COMMON_SURFACE_NODE_HIDE, RSContext::PurgeType::GENTLY);
346 }
347 if (GetName().substr(0, 3) == "SCB") {
348 context->MarkNeedPurge(ClearMemoryMoment::SCENEBOARD_SURFACE_NODE_HIDE, RSContext::PurgeType::STRONGLY);
349 }
350 }
351 }
352 #endif
353 if (IsAbilityComponent()) {
354 if (auto instanceRootNode = GetInstanceRootNode()) {
355 if (auto surfaceNode = instanceRootNode->ReinterpretCastTo<RSSurfaceRenderNode>()) {
356 surfaceNode->UpdateAbilityNodeIds(GetId(), IsOnTheTree());
357 }
358 }
359 }
360 }
361
OnResetParent()362 void RSSurfaceRenderNode::OnResetParent()
363 {
364 if (nodeType_ == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
365 ClearChildrenCache();
366 } else {
367 #ifndef ROSEN_CROSS_PLATFORM
368 auto& consumer = GetConsumer();
369 if (consumer != nullptr && !IsSelfDrawingType() && !IsAbilityComponent()) {
370 consumer->GoBackground();
371 }
372 #endif
373 }
374 }
375
SetIsNotifyUIBufferAvailable(bool available)376 void RSSurfaceRenderNode::SetIsNotifyUIBufferAvailable(bool available)
377 {
378 #ifdef USE_SURFACE_TEXTURE
379 auto texture = GetSurfaceTexture();
380 if (texture) {
381 texture->MarkUiFrameAvailable(available);
382 }
383 #endif
384 isNotifyUIBufferAvailable_.store(available);
385 }
386
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)387 void RSSurfaceRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
388 {
389 if (!visitor) {
390 return;
391 }
392 visitor->PrepareSurfaceRenderNode(*this);
393 }
394
Process(const std::shared_ptr<RSNodeVisitor> & visitor)395 void RSSurfaceRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
396 {
397 if (!visitor) {
398 return;
399 }
400 RSRenderNode::RenderTraceDebug();
401 visitor->ProcessSurfaceRenderNode(*this);
402 }
403
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)404 void RSSurfaceRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
405 {
406 needDrawAnimateProperty_ = true;
407 ProcessAnimatePropertyBeforeChildren(canvas, true);
408 needDrawAnimateProperty_ = false;
409 }
410
ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas & canvas,bool includeProperty)411 void RSSurfaceRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas& canvas, bool includeProperty)
412 {
413 if (GetCacheType() != CacheType::ANIMATE_PROPERTY && !needDrawAnimateProperty_) {
414 return;
415 }
416
417 const auto& property = GetRenderProperties();
418 const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
419 RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
420 RSPropertiesPainter::DrawShadow(property, canvas, &absClipRRect);
421 RSPropertiesPainter::DrawOutline(property, canvas);
422
423 #ifndef USE_ROSEN_DRAWING
424 if (!property.GetCornerRadius().IsZero()) {
425 canvas.clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
426 } else {
427 canvas.clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
428 }
429 #else
430 if (!property.GetCornerRadius().IsZero()) {
431 canvas.ClipRoundRect(
432 RSPropertiesPainter::RRect2DrawingRRect(absClipRRect), Drawing::ClipOp::INTERSECT, true);
433 } else {
434 canvas.ClipRect(Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()),
435 Drawing::ClipOp::INTERSECT, false);
436 }
437 #endif
438
439 #ifndef ROSEN_CROSS_PLATFORM
440 RSPropertiesPainter::DrawBackground(property, canvas, true, IsSelfDrawingNode() && (GetBuffer() != nullptr));
441 #else
442 RSPropertiesPainter::DrawBackground(property, canvas);
443 #endif
444 RSPropertiesPainter::DrawMask(property, canvas);
445 RSPropertiesPainter::DrawFilter(property, canvas, FilterType::BACKGROUND_FILTER);
446 #ifndef USE_ROSEN_DRAWING
447 SetTotalMatrix(canvas.getTotalMatrix());
448 #else
449 SetTotalMatrix(canvas.GetTotalMatrix());
450 #endif
451 }
452
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)453 void RSSurfaceRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
454 {
455 needDrawAnimateProperty_ = true;
456 ProcessAnimatePropertyAfterChildren(canvas);
457 needDrawAnimateProperty_ = false;
458 }
459
ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas & canvas)460 void RSSurfaceRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas& canvas)
461 {
462 if (GetCacheType() != CacheType::ANIMATE_PROPERTY && !needDrawAnimateProperty_) {
463 return;
464 }
465 const auto& property = GetRenderProperties();
466 RSPropertiesPainter::DrawFilter(property, canvas, FilterType::FOREGROUND_FILTER);
467 #ifndef USE_ROSEN_DRAWING
468 canvas.save();
469 if (GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE) {
470 auto geoPtr = (property.GetBoundsGeometry());
471 canvas.concat(geoPtr->GetMatrix());
472 }
473 RSPropertiesPainter::DrawOutline(property, canvas);
474 RSPropertiesPainter::DrawBorder(property, canvas);
475 canvas.restore();
476 #else
477 canvas.Save();
478 if (GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE) {
479 auto geoPtr = (property.GetBoundsGeometry());
480 canvas.ConcatMatrix(geoPtr->GetMatrix());
481 }
482 RSPropertiesPainter::DrawOutline(property, canvas);
483 RSPropertiesPainter::DrawBorder(property, canvas);
484 canvas.Restore();
485 #endif
486 }
487
SetContextBounds(const Vector4f bounds)488 void RSSurfaceRenderNode::SetContextBounds(const Vector4f bounds)
489 {
490 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetBounds>(GetId(), bounds);
491 SendCommandFromRT(command, GetId());
492 }
493
GetDirtyManager() const494 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNode::GetDirtyManager() const
495 {
496 return dirtyManager_;
497 }
498
GetCacheSurfaceDirtyManager() const499 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNode::GetCacheSurfaceDirtyManager() const
500 {
501 return cacheSurfaceDirtyManager_;
502 }
503
MarkUIHidden(bool isHidden)504 void RSSurfaceRenderNode::MarkUIHidden(bool isHidden)
505 {
506 isUIHidden_ = isHidden;
507 }
508
IsUIHidden() const509 bool RSSurfaceRenderNode::IsUIHidden() const
510 {
511 return isUIHidden_;
512 }
513
514 #ifndef USE_ROSEN_DRAWING
SetContextMatrix(const std::optional<SkMatrix> & matrix,bool sendMsg)515 void RSSurfaceRenderNode::SetContextMatrix(const std::optional<SkMatrix>& matrix, bool sendMsg)
516 #else
517 void RSSurfaceRenderNode::SetContextMatrix(const std::optional<Drawing::Matrix>& matrix, bool sendMsg)
518 #endif
519 {
520 if (contextMatrix_ == matrix) {
521 return;
522 }
523 contextMatrix_ = matrix;
524 SetContentDirty();
525 AddDirtyType(RSModifierType::SCALE);
526 AddDirtyType(RSModifierType::TRANSLATE);
527 if (!sendMsg) {
528 return;
529 }
530 // send a Command
531 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextMatrix>(GetId(), matrix);
532 SendCommandFromRT(command, GetId());
533 }
534
SetContextAlpha(float alpha,bool sendMsg)535 void RSSurfaceRenderNode::SetContextAlpha(float alpha, bool sendMsg)
536 {
537 if (contextAlpha_ == alpha) {
538 return;
539 }
540 contextAlpha_ = alpha;
541 SetContentDirty();
542 AddDirtyType(RSModifierType::ALPHA);
543 if (!sendMsg) {
544 return;
545 }
546 // send a Command
547 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextAlpha>(GetId(), alpha);
548 SendCommandFromRT(command, GetId());
549 }
550
551 #ifndef USE_ROSEN_DRAWING
SetContextClipRegion(const std::optional<SkRect> & clipRegion,bool sendMsg)552 void RSSurfaceRenderNode::SetContextClipRegion(const std::optional<SkRect>& clipRegion, bool sendMsg)
553 #else
554 void RSSurfaceRenderNode::SetContextClipRegion(const std::optional<Drawing::Rect>& clipRegion, bool sendMsg)
555 #endif
556 {
557 if (contextClipRect_ == clipRegion) {
558 return;
559 }
560 contextClipRect_ = clipRegion;
561 SetContentDirty();
562 AddDirtyType(RSModifierType::BOUNDS);
563 if (!sendMsg) {
564 return;
565 }
566 // send a Command
567 std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextClipRegion>(GetId(), clipRegion);
568 SendCommandFromRT(command, GetId());
569 }
SetBootAnimation(bool isBootAnimation)570 void RSSurfaceRenderNode::SetBootAnimation(bool isBootAnimation)
571 {
572 ROSEN_LOGD("SetBootAnimation:: id:%{public}" PRIu64 ", isBootAnimation:%{public}d",
573 GetId(), isBootAnimation);
574 isBootAnimation_ = isBootAnimation;
575 }
576
GetBootAnimation() const577 bool RSSurfaceRenderNode::GetBootAnimation() const
578 {
579 return isBootAnimation_;
580 }
581
SetSecurityLayer(bool isSecurityLayer)582 void RSSurfaceRenderNode::SetSecurityLayer(bool isSecurityLayer)
583 {
584 isSecurityLayer_ = isSecurityLayer;
585 SetDirty();
586 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(GetParent().lock());
587 if (parent != nullptr && parent->IsLeashWindow()) {
588 parent->SetSecurityLayer(isSecurityLayer);
589 parent->SetDirty();
590 }
591 }
592
GetSecurityLayer() const593 bool RSSurfaceRenderNode::GetSecurityLayer() const
594 {
595 return isSecurityLayer_;
596 }
597
SetSkipLayer(bool isSkipLayer)598 void RSSurfaceRenderNode::SetSkipLayer(bool isSkipLayer)
599 {
600 isSkipLayer_ = isSkipLayer;
601 SetDirty();
602 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(GetParent().lock());
603 if (parent != nullptr && parent->IsLeashWindow()) {
604 parent->SetSkipLayer(isSkipLayer);
605 parent->SetDirty();
606 }
607 }
608
GetSkipLayer() const609 bool RSSurfaceRenderNode::GetSkipLayer() const
610 {
611 return isSkipLayer_;
612 }
613
SetFingerprint(bool hasFingerprint)614 void RSSurfaceRenderNode::SetFingerprint(bool hasFingerprint)
615 {
616 hasFingerprint_ = hasFingerprint;
617 }
618
GetFingerprint() const619 bool RSSurfaceRenderNode::GetFingerprint() const
620 {
621 return hasFingerprint_;
622 }
623
SetForceUIFirst(bool forceUIFirst)624 void RSSurfaceRenderNode::SetForceUIFirst(bool forceUIFirst)
625 {
626 if (forceUIFirst) {
627 forceUIFirstChanged_ = true;
628 }
629 forceUIFirst_ = forceUIFirst;
630 }
GetForceUIFirst() const631 bool RSSurfaceRenderNode::GetForceUIFirst() const
632 {
633 return forceUIFirst_;
634 }
635
SetForceUIFirstChanged(bool forceUIFirstChanged)636 void RSSurfaceRenderNode::SetForceUIFirstChanged(bool forceUIFirstChanged)
637 {
638 forceUIFirstChanged_ = forceUIFirstChanged;
639 }
GetForceUIFirstChanged()640 bool RSSurfaceRenderNode::GetForceUIFirstChanged()
641 {
642 return forceUIFirstChanged_;
643 }
644
SetColorSpace(GraphicColorGamut colorSpace)645 void RSSurfaceRenderNode::SetColorSpace(GraphicColorGamut colorSpace)
646 {
647 colorSpace_ = colorSpace;
648 }
649
GetColorSpace() const650 GraphicColorGamut RSSurfaceRenderNode::GetColorSpace() const
651 {
652 return colorSpace_;
653 }
654
UpdateSurfaceDefaultSize(float width,float height)655 void RSSurfaceRenderNode::UpdateSurfaceDefaultSize(float width, float height)
656 {
657 #ifndef ROSEN_CROSS_PLATFORM
658 if (consumer_ != nullptr) {
659 consumer_->SetDefaultWidthAndHeight(width, height);
660 }
661 #else
662 #ifdef USE_SURFACE_TEXTURE
663 auto texture = GetSurfaceTexture();
664 if (texture) {
665 texture->UpdateSurfaceDefaultSize(width, height);
666 }
667 #endif
668 #endif
669 }
670
671 #ifndef ROSEN_CROSS_PLATFORM
GetBlendType()672 GraphicBlendType RSSurfaceRenderNode::GetBlendType()
673 {
674 return blendType_;
675 }
676
SetBlendType(GraphicBlendType blendType)677 void RSSurfaceRenderNode::SetBlendType(GraphicBlendType blendType)
678 {
679 blendType_ = blendType;
680 }
681 #endif
682
RegisterBufferAvailableListener(sptr<RSIBufferAvailableCallback> callback,bool isFromRenderThread)683 void RSSurfaceRenderNode::RegisterBufferAvailableListener(
684 sptr<RSIBufferAvailableCallback> callback, bool isFromRenderThread)
685 {
686 if (isFromRenderThread) {
687 std::lock_guard<std::mutex> lock(mutexRT_);
688 callbackFromRT_ = callback;
689 } else {
690 {
691 std::lock_guard<std::mutex> lock(mutexUI_);
692 callbackFromUI_ = callback;
693 }
694 isNotifyUIBufferAvailable_ = false;
695 }
696 }
697
RegisterBufferClearListener(sptr<RSIBufferClearCallback> callback)698 void RSSurfaceRenderNode::RegisterBufferClearListener(
699 sptr<RSIBufferClearCallback> callback)
700 {
701 std::lock_guard<std::mutex> lock(mutexClear_);
702 clearBufferCallback_ = callback;
703 }
704
SetNotifyRTBufferAvailable(bool isNotifyRTBufferAvailable)705 void RSSurfaceRenderNode::SetNotifyRTBufferAvailable(bool isNotifyRTBufferAvailable)
706 {
707 isNotifyRTBufferAvailable_ = isNotifyRTBufferAvailable;
708 std::lock_guard<std::mutex> lock(mutexClear_);
709 if (clearBufferCallback_) {
710 clearBufferCallback_->OnBufferClear();
711 }
712 }
713
ConnectToNodeInRenderService()714 void RSSurfaceRenderNode::ConnectToNodeInRenderService()
715 {
716 ROSEN_LOGI("RSSurfaceRenderNode::ConnectToNodeInRenderService nodeId = %{public}" PRIu64, GetId());
717 auto renderServiceClient =
718 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
719 if (renderServiceClient != nullptr) {
720 renderServiceClient->RegisterBufferAvailableListener(
721 GetId(), [weakThis = weak_from_this()]() {
722 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(weakThis.lock());
723 if (node == nullptr) {
724 return;
725 }
726 node->NotifyRTBufferAvailable(node->GetIsTextureExportNode());
727 }, true);
728 renderServiceClient->RegisterBufferClearListener(
729 GetId(), [weakThis = weak_from_this()]() {
730 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(weakThis.lock());
731 if (node == nullptr) {
732 return;
733 }
734 node->SetNotifyRTBufferAvailable(false);
735 });
736 }
737 }
738
NotifyRTBufferAvailable(bool isTextureExportNode)739 void RSSurfaceRenderNode::NotifyRTBufferAvailable(bool isTextureExportNode)
740 {
741 // In RS, "isNotifyRTBufferAvailable_ = true" means buffer is ready and need to trigger ipc callback.
742 // In RT, "isNotifyRTBufferAvailable_ = true" means RT know that RS have had available buffer
743 // and ready to trigger "callbackForRenderThreadRefresh_" to "clip" on parent surface.
744 if (!isTextureExportNode) {
745 isNotifyRTBufferAvailablePre_ = isNotifyRTBufferAvailable_;
746 if (isNotifyRTBufferAvailable_) {
747 return;
748 }
749 isNotifyRTBufferAvailable_ = true;
750 }
751
752 if (isRefresh_) {
753 ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %{public}" PRIu64 " RenderThread", GetId());
754 RSRTRefreshCallback::Instance().ExcuteRefresh();
755 }
756
757 {
758 std::lock_guard<std::mutex> lock(mutexRT_);
759 if (callbackFromRT_) {
760 ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %{public}" PRIu64 " RenderService",
761 GetId());
762 callbackFromRT_->OnBufferAvailable();
763 }
764 if (!isRefresh_ && !callbackFromRT_) {
765 isNotifyRTBufferAvailable_ = false;
766 }
767 }
768 }
769
NotifyUIBufferAvailable()770 void RSSurfaceRenderNode::NotifyUIBufferAvailable()
771 {
772 if (isNotifyUIBufferAvailable_) {
773 return;
774 }
775 isNotifyUIBufferAvailable_ = true;
776 {
777 std::lock_guard<std::mutex> lock(mutexUI_);
778 if (callbackFromUI_) {
779 ROSEN_LOGD("RSSurfaceRenderNode::NotifyUIBufferAvailable nodeId = %{public}" PRIu64, GetId());
780 callbackFromUI_->OnBufferAvailable();
781 #ifdef OHOS_PLATFORM
782 if (IsAppWindow()) {
783 RSJankStats::GetInstance().SetAppFirstFrame(ExtractPid(GetId()));
784 }
785 #endif
786 }
787 }
788 }
789
IsNotifyRTBufferAvailable() const790 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailable() const
791 {
792 #if defined(ROSEN_ANDROID) || defined(ROSEN_IOS)
793 return true;
794 #else
795 return isNotifyRTBufferAvailable_;
796 #endif
797 }
798
IsNotifyRTBufferAvailablePre() const799 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailablePre() const
800 {
801 #if defined(ROSEN_ANDROID) || defined(ROSEN_IOS)
802 return true;
803 #else
804 return isNotifyRTBufferAvailablePre_;
805 #endif
806 }
807
IsNotifyUIBufferAvailable() const808 bool RSSurfaceRenderNode::IsNotifyUIBufferAvailable() const
809 {
810 return isNotifyUIBufferAvailable_;
811 }
812
SetCallbackForRenderThreadRefresh(bool isRefresh)813 void RSSurfaceRenderNode::SetCallbackForRenderThreadRefresh(bool isRefresh)
814 {
815 isRefresh_ = isRefresh;
816 }
817
NeedSetCallbackForRenderThreadRefresh()818 bool RSSurfaceRenderNode::NeedSetCallbackForRenderThreadRefresh()
819 {
820 return !isRefresh_;
821 }
822
IsStartAnimationFinished() const823 bool RSSurfaceRenderNode::IsStartAnimationFinished() const
824 {
825 return startAnimationFinished_;
826 }
827
SetStartAnimationFinished()828 void RSSurfaceRenderNode::SetStartAnimationFinished()
829 {
830 RS_LOGD("RSSurfaceRenderNode::SetStartAnimationFinished");
831 startAnimationFinished_ = true;
832 }
833
UpdateDirtyIfFrameBufferConsumed()834 bool RSSurfaceRenderNode::UpdateDirtyIfFrameBufferConsumed()
835 {
836 if (isCurrentFrameBufferConsumed_) {
837 SetContentDirty();
838 return true;
839 }
840 return false;
841 }
842
IsSurfaceInStartingWindowStage() const843 bool RSSurfaceRenderNode::IsSurfaceInStartingWindowStage() const
844 {
845 auto parentPtr = this->GetParent().lock();
846 if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
847 auto surfaceParentPtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentPtr);
848 if (surfaceParentPtr->GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE &&
849 !this->IsNotifyUIBufferAvailable()) {
850 return true;
851 }
852 }
853 return false;
854 }
855
IsParentLeashWindowInScale() const856 bool RSSurfaceRenderNode::IsParentLeashWindowInScale() const
857 {
858 auto parentPtr = this->GetParent().lock();
859 if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
860 auto surfaceParentPtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentPtr);
861 if (surfaceParentPtr->IsLeashWindow() && surfaceParentPtr->IsScale()) {
862 return true;
863 }
864 }
865 return false;
866 }
867
GetSurfaceOcclusionRect(bool isUniRender)868 Occlusion::Rect RSSurfaceRenderNode::GetSurfaceOcclusionRect(bool isUniRender)
869 {
870 Occlusion::Rect occlusionRect;
871 if (isUniRender) {
872 occlusionRect = Occlusion::Rect {GetOldDirtyInSurface()};
873 } else {
874 occlusionRect = Occlusion::Rect {GetDstRect()};
875 }
876 return occlusionRect;
877 }
878
QueryIfAllHwcChildrenForceDisabledByFilter()879 bool RSSurfaceRenderNode::QueryIfAllHwcChildrenForceDisabledByFilter()
880 {
881 std::shared_ptr<RSSurfaceRenderNode> appWindow;
882 for (auto& child : *GetSortedChildren()) {
883 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
884 if (node && node->IsAppWindow()) {
885 appWindow = node;
886 break;
887 }
888 }
889 if (appWindow) {
890 auto hardwareEnabledNodes = appWindow->GetChildHardwareEnabledNodes();
891 for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
892 auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
893 if (hardwareEnabledNodePtr && !hardwareEnabledNodePtr->IsHardwareForcedDisabledByFilter()) {
894 return false;
895 }
896 }
897 }
898 return true;
899 }
900
AccumulateOcclusionRegion(Occlusion::Region & accumulatedRegion,Occlusion::Region & curRegion,bool & hasFilterCacheOcclusion,bool isUniRender,bool filterCacheOcclusionEnabled)901 void RSSurfaceRenderNode::AccumulateOcclusionRegion(Occlusion::Region& accumulatedRegion,
902 Occlusion::Region& curRegion,
903 bool& hasFilterCacheOcclusion,
904 bool isUniRender,
905 bool filterCacheOcclusionEnabled)
906 {
907 // when surfacenode is in starting window stage, do not occlude other window surfaces
908 // fix gray block when directly open app (i.e. setting) from notification center
909 if (IsSurfaceInStartingWindowStage()) {
910 return;
911 }
912 if (!isUniRender) {
913 bool diff =
914 #ifndef ROSEN_CROSS_PLATFORM
915 (GetDstRect().width_ > GetBuffer()->GetWidth() || GetDstRect().height_ > GetBuffer()->GetHeight()) &&
916 #endif
917 GetRenderProperties().GetFrameGravity() != Gravity::RESIZE &&
918 ROSEN_EQ(GetGlobalAlpha(), 1.0f);
919 if (!IsTransparent() && !diff) {
920 accumulatedRegion.OrSelf(curRegion);
921 }
922 }
923
924 if (GetName().find("hisearch") != std::string::npos) {
925 return;
926 }
927 SetTreatedAsTransparent(false);
928 // when a surfacenode is in animation (i.e. 3d animation), its dstrect cannot be trusted, we treated it as a full
929 // transparent layer.
930 if ((GetAnimateState() || IsParentLeashWindowInScale()) && !isOcclusionInSpecificScenes_) {
931 SetTreatedAsTransparent(true);
932 return;
933 }
934
935 // full surfacenode valid filter cache can be treated as opaque
936 if (filterCacheOcclusionEnabled && IsTransparent() && GetFilterCacheValidForOcclusion()) {
937 accumulatedRegion.OrSelf(curRegion);
938 hasFilterCacheOcclusion = true;
939 } else {
940 accumulatedRegion.OrSelf(GetOpaqueRegion());
941 }
942 return;
943 }
944
GetVisibleLevelForWMS(RSVisibleLevel visibleLevel)945 WINDOW_LAYER_INFO_TYPE RSSurfaceRenderNode::GetVisibleLevelForWMS(RSVisibleLevel visibleLevel)
946 {
947 switch (visibleLevel) {
948 case RSVisibleLevel::RS_INVISIBLE:
949 return WINDOW_LAYER_INFO_TYPE::SEMI_VISIBLE;
950 case RSVisibleLevel::RS_ALL_VISIBLE:
951 return WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE;
952 case RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE:
953 case RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE:
954 return WINDOW_LAYER_INFO_TYPE::SEMI_VISIBLE;
955 default:
956 break;
957 }
958 return WINDOW_LAYER_INFO_TYPE::SEMI_VISIBLE;
959 }
960
IsNeedSetVSync()961 bool RSSurfaceRenderNode::IsNeedSetVSync()
962 {
963 return GetName().substr(0, SCB_NODE_NAME_PREFIX_LENGTH) != "SCB";
964 }
965
SetVisibleRegionRecursive(const Occlusion::Region & region,VisibleData & visibleVec,std::map<uint32_t,RSVisibleLevel> & pidVisMap,bool needSetVisibleRegion,RSVisibleLevel visibleLevel,bool isSystemAnimatedScenes)966 void RSSurfaceRenderNode::SetVisibleRegionRecursive(const Occlusion::Region& region,
967 VisibleData& visibleVec,
968 std::map<uint32_t, RSVisibleLevel>& pidVisMap,
969 bool needSetVisibleRegion,
970 RSVisibleLevel visibleLevel,
971 bool isSystemAnimatedScenes)
972 {
973 if (nodeType_ == RSSurfaceNodeType::SELF_DRAWING_NODE || IsAbilityComponent()) {
974 SetOcclusionVisible(true);
975 visibleVec.emplace_back(std::make_pair(GetId(), ALL_VISIBLE));
976 return;
977 }
978
979 bool vis = !region.IsEmpty();
980 if (vis) {
981 visibleVec.emplace_back(std::make_pair(GetId(), GetVisibleLevelForWMS(visibleLevel)));
982 }
983
984 // collect visible changed pid
985 if (qosPidCal_ && GetType() == RSRenderNodeType::SURFACE_NODE && !isSystemAnimatedScenes) {
986 uint32_t tmpPid = ExtractPid(GetId());
987 pidVisMap[tmpPid] = !IsNeedSetVSync() ? RSVisibleLevel::RS_ALL_VISIBLE : visibleLevel;
988 }
989
990 visibleRegionForCallBack_ = region;
991 if (needSetVisibleRegion) {
992 visibleRegion_ = region;
993 SetOcclusionVisible(vis);
994 }
995 // when there is filter cache occlusion, also save occlusion status without filter cache
996 SetOcclusionVisibleWithoutFilter(vis);
997
998 for (auto& child : *GetChildren()) {
999 if (auto surfaceChild = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)) {
1000 surfaceChild->SetVisibleRegionRecursive(region, visibleVec, pidVisMap, needSetVisibleRegion,
1001 visibleLevel, isSystemAnimatedScenes);
1002 }
1003 }
1004 }
1005
SubNodeIntersectWithExtraDirtyRegion(const RectI & r) const1006 bool RSSurfaceRenderNode::SubNodeIntersectWithExtraDirtyRegion(const RectI& r) const
1007 {
1008 if (!isDirtyRegionAlignedEnable_) {
1009 return false;
1010 }
1011 if (!extraDirtyRegionAfterAlignmentIsEmpty_) {
1012 return extraDirtyRegionAfterAlignment_.IsIntersectWith(r);
1013 }
1014 return false;
1015 }
1016
SubNodeIntersectWithDirty(const RectI & r) const1017 bool RSSurfaceRenderNode::SubNodeIntersectWithDirty(const RectI& r) const
1018 {
1019 Occlusion::Rect nodeRect { r.left_, r.top_, r.GetRight(), r.GetBottom() };
1020 // if current node rect r is in global dirtyregion, it CANNOT be skipped
1021 if (!globalDirtyRegionIsEmpty_) {
1022 auto globalRect = globalDirtyRegion_.IsIntersectWith(nodeRect);
1023 if (globalRect) {
1024 return true;
1025 }
1026 }
1027 // if current node is in visible dirtyRegion, it CANNOT be skipped
1028 bool localIntersect = visibleDirtyRegion_.IsIntersectWith(nodeRect);
1029 if (localIntersect) {
1030 return true;
1031 }
1032 // if current node is transparent
1033 if (IsTransparent() || IsCurrentNodeInTransparentRegion(nodeRect) || IsTreatedAsTransparent()) {
1034 return dirtyRegionBelowCurrentLayer_.IsIntersectWith(nodeRect);
1035 }
1036 return false;
1037 }
1038
SubNodeNeedDraw(const RectI & r,PartialRenderType opDropType) const1039 bool RSSurfaceRenderNode::SubNodeNeedDraw(const RectI &r, PartialRenderType opDropType) const
1040 {
1041 if (dirtyManager_ == nullptr) {
1042 return true;
1043 }
1044 switch (opDropType) {
1045 case PartialRenderType::SET_DAMAGE_AND_DROP_OP:
1046 return SubNodeIntersectWithDirty(r);
1047 case PartialRenderType::SET_DAMAGE_AND_DROP_OP_OCCLUSION:
1048 return SubNodeVisible(r);
1049 case PartialRenderType::SET_DAMAGE_AND_DROP_OP_NOT_VISIBLEDIRTY:
1050 // intersect with self visible dirty or other surfaces' extra dirty region after alignment
1051 return SubNodeVisible(r) && (SubNodeIntersectWithDirty(r) ||
1052 SubNodeIntersectWithExtraDirtyRegion(r));
1053 case PartialRenderType::DISABLED:
1054 case PartialRenderType::SET_DAMAGE:
1055 default:
1056 return true;
1057 }
1058 return true;
1059 }
1060
ResetSurfaceOpaqueRegion(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow,const Vector4<int> & cornerRadius)1061 void RSSurfaceRenderNode::ResetSurfaceOpaqueRegion(const RectI& screeninfo, const RectI& absRect,
1062 const ScreenRotation screenRotation, const bool isFocusWindow, const Vector4<int>& cornerRadius)
1063 {
1064 Occlusion::Rect absRectR {absRect};
1065 Occlusion::Region oldOpaqueRegion { opaqueRegion_ };
1066
1067 // The transparent region of surfaceNode should include shadow area
1068 Occlusion::Rect dirtyRect {GetOldDirty()};
1069 transparentRegion_ = Occlusion::Region{dirtyRect};
1070
1071 if (IsTransparent()) {
1072 opaqueRegion_ = Occlusion::Region();
1073 } else {
1074 if (IsAppWindow() && HasContainerWindow()) {
1075 opaqueRegion_ = ResetOpaqueRegion(absRect, screenRotation, isFocusWindow);
1076 } else {
1077 if (!cornerRadius.IsZero()) {
1078 auto maxRadius = std::max({ cornerRadius.x_, cornerRadius.y_, cornerRadius.z_, cornerRadius.w_ });
1079 Vector4<int> dstCornerRadius((cornerRadius.x_ > 0 ? maxRadius : 0),
1080 (cornerRadius.y_ > 0 ? maxRadius : 0),
1081 (cornerRadius.z_ > 0 ? maxRadius : 0),
1082 (cornerRadius.w_ > 0 ? maxRadius : 0));
1083 opaqueRegion_ = SetCornerRadiusOpaqueRegion(absRect, dstCornerRadius);
1084 } else {
1085 opaqueRegion_ = Occlusion::Region{absRectR};
1086 }
1087 }
1088 transparentRegion_.SubSelf(opaqueRegion_);
1089 }
1090 Occlusion::Rect screen{screeninfo};
1091 Occlusion::Region screenRegion{screen};
1092 transparentRegion_.AndSelf(screenRegion);
1093 opaqueRegion_.AndSelf(screenRegion);
1094 opaqueRegionChanged_ = !oldOpaqueRegion.Xor(opaqueRegion_).IsEmpty();
1095 ResetSurfaceContainerRegion(screeninfo, absRect, screenRotation);
1096 }
1097
CalcFilterCacheValidForOcclusion()1098 void RSSurfaceRenderNode::CalcFilterCacheValidForOcclusion()
1099 {
1100 if (!dirtyManager_) {
1101 return;
1102 }
1103 isFilterCacheStatusChanged_ = false;
1104 bool currentCacheValidForOcclusion = isFilterCacheFullyCovered_ && dirtyManager_->IsFilterCacheRectValid();
1105 if (isFilterCacheValidForOcclusion_ != currentCacheValidForOcclusion) {
1106 isFilterCacheValidForOcclusion_ = currentCacheValidForOcclusion;
1107 isFilterCacheStatusChanged_ = true;
1108 }
1109 }
1110
UpdateFilterNodes(const std::shared_ptr<RSRenderNode> & nodePtr)1111 void RSSurfaceRenderNode::UpdateFilterNodes(const std::shared_ptr<RSRenderNode>& nodePtr)
1112 {
1113 if (nodePtr == nullptr) {
1114 return;
1115 }
1116 filterNodes_.emplace_back(nodePtr);
1117 }
1118
UpdateDrawingCacheNodes(const std::shared_ptr<RSRenderNode> & nodePtr)1119 void RSSurfaceRenderNode::UpdateDrawingCacheNodes(const std::shared_ptr<RSRenderNode>& nodePtr)
1120 {
1121 if (nodePtr == nullptr) {
1122 return;
1123 }
1124 drawingCacheNodes_.emplace(nodePtr->GetId(), nodePtr);
1125 }
1126
ResetDrawingCacheStatusIfNodeStatic(std::unordered_map<NodeId,std::unordered_set<NodeId>> & allRects)1127 void RSSurfaceRenderNode::ResetDrawingCacheStatusIfNodeStatic(
1128 std::unordered_map<NodeId, std::unordered_set<NodeId>>& allRects)
1129 {
1130 // traversal drawing cache nodes including app window
1131 EraseIf(drawingCacheNodes_, [this, &allRects](const auto& pair) {
1132 auto node = pair.second.lock();
1133 if (node == nullptr || !node->IsOnTheTree()) {
1134 return true;
1135 }
1136 node->SetDrawingCacheChanged(false);
1137 node->GetFilterRectsInCache(allRects);
1138 return false;
1139 });
1140 }
1141
UpdateFilterCacheStatusWithVisible(bool visible)1142 void RSSurfaceRenderNode::UpdateFilterCacheStatusWithVisible(bool visible)
1143 {
1144 if (visible == prevVisible_) {
1145 return;
1146 }
1147 prevVisible_ = visible;
1148 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1149 if (!visible && !filterNodes_.empty() && !isOcclusionVisibleWithoutFilter_) {
1150 for (auto& node : filterNodes_) {
1151 node->GetMutableRenderProperties().ClearFilterCache();
1152 }
1153 }
1154 #endif
1155 }
1156
UpdateFilterCacheStatusIfNodeStatic(const RectI & clipRect,bool isRotationChanged)1157 void RSSurfaceRenderNode::UpdateFilterCacheStatusIfNodeStatic(const RectI& clipRect, bool isRotationChanged)
1158 {
1159 if (!dirtyManager_) {
1160 return;
1161 }
1162 // traversal filter nodes including app window
1163 for (auto node : filterNodes_) {
1164 if (node == nullptr || !node->IsOnTheTree() || !node->GetRenderProperties().NeedFilter()) {
1165 continue;
1166 }
1167 if (node->IsInstanceOf<RSEffectRenderNode>()) {
1168 if (auto effectNode = node->ReinterpretCastTo<RSEffectRenderNode>()) {
1169 effectNode->SetRotationChanged(isRotationChanged);
1170 }
1171 }
1172 node->UpdateFilterCacheWithDirty(*dirtyManager_, false);
1173 node->UpdateFilterCacheWithDirty(*dirtyManager_, true);
1174 node->UpdateFilterCacheManagerWithCacheRegion(*dirtyManager_, clipRect);
1175 }
1176 SetFilterCacheFullyCovered(false);
1177 if (IsTransparent() && dirtyManager_->IfCacheableFilterRectFullyCover(GetOldDirtyInSurface())) {
1178 SetFilterCacheFullyCovered(true);
1179 RS_LOGD("UpdateFilterCacheStatusIfNodeStatic surfacenode %{public}" PRIu64 " [%{public}s] rectsize %{public}s",
1180 GetId(), GetName().c_str(), GetOldDirtyInSurface().ToString().c_str());
1181 }
1182 CalcFilterCacheValidForOcclusion();
1183 }
1184
GetWindowCornerRadius()1185 Vector4f RSSurfaceRenderNode::GetWindowCornerRadius()
1186 {
1187 if (!GetRenderProperties().GetCornerRadius().IsZero()) {
1188 return GetRenderProperties().GetCornerRadius();
1189 }
1190 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(GetParent().lock());
1191 if (parent != nullptr && parent->IsLeashWindow()) {
1192 return parent->GetRenderProperties().GetCornerRadius();
1193 }
1194 return Vector4f();
1195 }
1196
ResetOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow) const1197 Occlusion::Region RSSurfaceRenderNode::ResetOpaqueRegion(const RectI& absRect,
1198 const ScreenRotation screenRotation, const bool isFocusWindow) const
1199 {
1200 if (isFocusWindow) {
1201 return SetFocusedWindowOpaqueRegion(absRect, screenRotation);
1202 } else {
1203 return SetUnfocusedWindowOpaqueRegion(absRect, screenRotation);
1204 }
1205 }
1206
Update(bool hasContainer,float density)1207 void RSSurfaceRenderNode::ContainerConfig::Update(bool hasContainer, float density)
1208 {
1209 this->hasContainerWindow_ = hasContainer;
1210 this->density = density;
1211
1212 // px = vp * density
1213 float containerTitleHeight_ = CONTAINER_TITLE_HEIGHT * density;
1214 float containerContentPadding_ = CONTENT_PADDING * density;
1215 float containerBorderWidth_ = CONTAINER_BORDER_WIDTH * density;
1216 float containerOutRadius_ = CONTAINER_OUTER_RADIUS * density;
1217 float containerInnerRadius_ = CONTAINER_INNER_RADIUS * density;
1218
1219 this->outR = RoundFloor(containerOutRadius_);
1220 this->inR = RoundFloor(containerInnerRadius_);
1221 this->bp = RoundFloor(containerBorderWidth_ + containerContentPadding_);
1222 this->bt = RoundFloor(containerBorderWidth_ + containerTitleHeight_);
1223 }
1224
1225 /*
1226 If a surfacenode with containerwindow is not focus window, then its opaque
1227 region is absRect minus four roundCorner corresponding small rectangles.
1228 This corners removed region can be assembled with two crossed rectangles.
1229 Furthermore, when the surfacenode is not focus window, the inner content roundrect's
1230 boundingbox rect can be set opaque.
1231 */
SetUnfocusedWindowOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation) const1232 Occlusion::Region RSSurfaceRenderNode::SetUnfocusedWindowOpaqueRegion(const RectI& absRect,
1233 const ScreenRotation screenRotation) const
1234 {
1235 Occlusion::Rect opaqueRect1{ absRect.left_ + containerConfig_.outR,
1236 absRect.top_,
1237 absRect.GetRight() - containerConfig_.outR,
1238 absRect.GetBottom()};
1239 Occlusion::Rect opaqueRect2{ absRect.left_,
1240 absRect.top_ + containerConfig_.outR,
1241 absRect.GetRight(),
1242 absRect.GetBottom() - containerConfig_.outR};
1243 Occlusion::Region r1{opaqueRect1};
1244 Occlusion::Region r2{opaqueRect2};
1245 Occlusion::Region opaqueRegion = r1.Or(r2);
1246
1247 switch (screenRotation) {
1248 case ScreenRotation::ROTATION_0: {
1249 Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
1250 absRect.top_ + containerConfig_.bt,
1251 absRect.GetRight() - containerConfig_.bp,
1252 absRect.GetBottom() - containerConfig_.bp};
1253 Occlusion::Region r3{opaqueRect3};
1254 opaqueRegion.OrSelf(r3);
1255 break;
1256 }
1257 case ScreenRotation::ROTATION_90: {
1258 Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bt,
1259 absRect.top_ + containerConfig_.bp,
1260 absRect.GetRight() - containerConfig_.bp,
1261 absRect.GetBottom() - containerConfig_.bp};
1262 Occlusion::Region r3{opaqueRect3};
1263 opaqueRegion.OrSelf(r3);
1264 break;
1265 }
1266 case ScreenRotation::ROTATION_180: {
1267 Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
1268 absRect.top_ + containerConfig_.bp,
1269 absRect.GetRight() - containerConfig_.bp,
1270 absRect.GetBottom() - containerConfig_.bt};
1271 Occlusion::Region r3{opaqueRect3};
1272 opaqueRegion.OrSelf(r3);
1273 break;
1274 }
1275 case ScreenRotation::ROTATION_270: {
1276 Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
1277 absRect.top_ + containerConfig_.bp,
1278 absRect.GetRight() - containerConfig_.bt,
1279 absRect.GetBottom() - containerConfig_.bp};
1280 Occlusion::Region r3{opaqueRect3};
1281 opaqueRegion.OrSelf(r3);
1282 break;
1283 }
1284 default: {
1285 Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
1286 absRect.top_ + containerConfig_.bt,
1287 absRect.GetRight() - containerConfig_.bp,
1288 absRect.GetBottom() - containerConfig_.bp};
1289 Occlusion::Region r3{opaqueRect3};
1290 opaqueRegion.OrSelf(r3);
1291 break;
1292 }
1293 }
1294 return opaqueRegion;
1295 }
1296
1297 /*
1298 If a surfacenode with containerwindow is a focused window, then its containerWindow region
1299 should be set transparent, including: title, content padding area, border, and content corners.
1300 Note this region is not centrosymmetric, hence it should be differentiated under different
1301 screen rotation state as top/left/bottom/right has changed when screen rotated.
1302 */
SetFocusedWindowOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation) const1303 Occlusion::Region RSSurfaceRenderNode::SetFocusedWindowOpaqueRegion(const RectI& absRect,
1304 const ScreenRotation screenRotation) const
1305 {
1306 Occlusion::Region opaqueRegion;
1307 switch (screenRotation) {
1308 case ScreenRotation::ROTATION_0: {
1309 Occlusion::Rect opaqueRect1{
1310 absRect.left_ + containerConfig_.bp,
1311 absRect.top_ + containerConfig_.bt + containerConfig_.inR,
1312 absRect.GetRight() - containerConfig_.bp,
1313 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1314 Occlusion::Rect opaqueRect2{
1315 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
1316 absRect.top_ + containerConfig_.bt,
1317 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
1318 absRect.GetBottom() - containerConfig_.bp};
1319 Occlusion::Region r1{opaqueRect1};
1320 Occlusion::Region r2{opaqueRect2};
1321 opaqueRegion = r1.Or(r2);
1322 break;
1323 }
1324 case ScreenRotation::ROTATION_90: {
1325 Occlusion::Rect opaqueRect1{
1326 absRect.left_ + containerConfig_.bt + containerConfig_.inR,
1327 absRect.top_ + containerConfig_.bp,
1328 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
1329 absRect.GetBottom() - containerConfig_.bp};
1330 Occlusion::Rect opaqueRect2{
1331 absRect.left_ + containerConfig_.bt,
1332 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
1333 absRect.GetRight() - containerConfig_.bp,
1334 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1335 Occlusion::Region r1{opaqueRect1};
1336 Occlusion::Region r2{opaqueRect2};
1337 opaqueRegion = r1.Or(r2);
1338 break;
1339 }
1340 case ScreenRotation::ROTATION_180: {
1341 Occlusion::Rect opaqueRect1{
1342 absRect.left_ + containerConfig_.bp,
1343 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
1344 absRect.GetRight() - containerConfig_.bp,
1345 absRect.GetBottom() - containerConfig_.bt - containerConfig_.inR};
1346 Occlusion::Rect opaqueRect2{
1347 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
1348 absRect.top_ + containerConfig_.bp,
1349 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
1350 absRect.GetBottom() - containerConfig_.bt};
1351 Occlusion::Region r1{opaqueRect1};
1352 Occlusion::Region r2{opaqueRect2};
1353 opaqueRegion = r1.Or(r2);
1354 break;
1355 }
1356 case ScreenRotation::ROTATION_270: {
1357 Occlusion::Rect opaqueRect1{
1358 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
1359 absRect.top_ + containerConfig_.bp,
1360 absRect.GetRight() - containerConfig_.bt - containerConfig_.inR,
1361 absRect.GetBottom() - containerConfig_.bp};
1362 Occlusion::Rect opaqueRect2{
1363 absRect.left_ + containerConfig_.bp,
1364 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
1365 absRect.GetRight() - containerConfig_.bt,
1366 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1367 Occlusion::Region r1{opaqueRect1};
1368 Occlusion::Region r2{opaqueRect2};
1369 opaqueRegion = r1.Or(r2);
1370 break;
1371 }
1372 default: {
1373 Occlusion::Rect opaqueRect1{
1374 absRect.left_ + containerConfig_.bp,
1375 absRect.top_ + containerConfig_.bt + containerConfig_.inR,
1376 absRect.GetRight() - containerConfig_.bp,
1377 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1378 Occlusion::Rect opaqueRect2{
1379 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
1380 absRect.top_ + containerConfig_.bt,
1381 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
1382 absRect.GetBottom() - containerConfig_.bp};
1383 Occlusion::Region r1{opaqueRect1};
1384 Occlusion::Region r2{opaqueRect2};
1385 opaqueRegion = r1.Or(r2);
1386 break;
1387 }
1388 }
1389 return opaqueRegion;
1390 }
1391
SetCornerRadiusOpaqueRegion(const RectI & absRect,const Vector4<int> & cornerRadius) const1392 Occlusion::Region RSSurfaceRenderNode::SetCornerRadiusOpaqueRegion(
1393 const RectI& absRect, const Vector4<int>& cornerRadius) const
1394 {
1395 Occlusion::Rect opaqueRect0{ absRect.GetLeft(), absRect.GetTop(),
1396 absRect.GetRight(), absRect.GetBottom()};
1397 Occlusion::Rect opaqueRect1{ absRect.GetLeft(), absRect.GetTop(),
1398 absRect.GetLeft() + cornerRadius.x_, absRect.GetTop() + cornerRadius.x_};
1399 Occlusion::Rect opaqueRect2{ absRect.GetRight() - cornerRadius.y_, absRect.GetTop(),
1400 absRect.GetRight(), absRect.GetTop() + cornerRadius.y_};
1401 Occlusion::Rect opaqueRect3{ absRect.GetRight() - cornerRadius.z_, absRect.GetBottom() - cornerRadius.z_,
1402 absRect.GetRight(), absRect.GetBottom()};
1403 Occlusion::Rect opaqueRect4{ absRect.GetLeft(), absRect.GetBottom() - cornerRadius.w_,
1404 absRect.GetLeft() + cornerRadius.w_, absRect.GetBottom()};
1405
1406 Occlusion::Region r0{opaqueRect0};
1407 Occlusion::Region r1{opaqueRect1};
1408 Occlusion::Region r2{opaqueRect2};
1409 Occlusion::Region r3{opaqueRect3};
1410 Occlusion::Region r4{opaqueRect4};
1411 Occlusion::Region opaqueRegion = r0.Sub(r1).Sub(r2).Sub(r3).Sub(r4);
1412 return opaqueRegion;
1413 }
1414
ResetSurfaceContainerRegion(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation)1415 void RSSurfaceRenderNode::ResetSurfaceContainerRegion(const RectI& screeninfo, const RectI& absRect,
1416 const ScreenRotation screenRotation)
1417 {
1418 if (!HasContainerWindow()) {
1419 containerRegion_ = Occlusion::Region{};
1420 return;
1421 }
1422 Occlusion::Region absRegion{Occlusion::Rect{absRect}};
1423 Occlusion::Rect innerRect;
1424 switch (screenRotation) {
1425 case ScreenRotation::ROTATION_0: {
1426 innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1427 absRect.top_ + containerConfig_.bt,
1428 absRect.GetRight() - containerConfig_.bp,
1429 absRect.GetBottom() - containerConfig_.bp};
1430 break;
1431 }
1432 case ScreenRotation::ROTATION_90: {
1433 innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bt,
1434 absRect.top_ + containerConfig_.bp,
1435 absRect.GetRight() - containerConfig_.bp,
1436 absRect.GetBottom() - containerConfig_.bp};
1437 break;
1438 }
1439 case ScreenRotation::ROTATION_180: {
1440 innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1441 absRect.top_ + containerConfig_.bp,
1442 absRect.GetRight() - containerConfig_.bp,
1443 absRect.GetBottom() - containerConfig_.bt};
1444 break;
1445 }
1446 case ScreenRotation::ROTATION_270: {
1447 innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1448 absRect.top_ + containerConfig_.bp,
1449 absRect.GetRight() - containerConfig_.bt,
1450 absRect.GetBottom() - containerConfig_.bp};
1451 break;
1452 }
1453 default: {
1454 innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1455 absRect.top_ + containerConfig_.bt,
1456 absRect.GetRight() - containerConfig_.bp,
1457 absRect.GetBottom() - containerConfig_.bp};
1458 break;
1459 }
1460 }
1461 Occlusion::Region innerRectRegion{innerRect};
1462 containerRegion_ = absRegion.Sub(innerRectRegion);
1463 }
1464
CheckOpaqueRegionBaseInfo(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow,const Vector4<int> & cornerRadius)1465 bool RSSurfaceRenderNode::CheckOpaqueRegionBaseInfo(const RectI& screeninfo, const RectI& absRect,
1466 const ScreenRotation screenRotation, const bool isFocusWindow, const Vector4<int>& cornerRadius)
1467 {
1468 return opaqueRegionBaseInfo_.screenRect_ == screeninfo &&
1469 opaqueRegionBaseInfo_.absRect_ == absRect &&
1470 opaqueRegionBaseInfo_.screenRotation_ == screenRotation &&
1471 opaqueRegionBaseInfo_.isFocusWindow_ == isFocusWindow &&
1472 opaqueRegionBaseInfo_.cornerRadius_ == cornerRadius &&
1473 opaqueRegionBaseInfo_.isTransparent_ == IsTransparent() &&
1474 opaqueRegionBaseInfo_.hasContainerWindow_ == HasContainerWindow();
1475 }
1476
SetOpaqueRegionBaseInfo(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow,const Vector4<int> & cornerRadius)1477 void RSSurfaceRenderNode::SetOpaqueRegionBaseInfo(const RectI& screeninfo, const RectI& absRect,
1478 const ScreenRotation screenRotation, const bool isFocusWindow, const Vector4<int>& cornerRadius)
1479 {
1480 opaqueRegionBaseInfo_.screenRect_ = screeninfo;
1481 opaqueRegionBaseInfo_.absRect_ = absRect;
1482 opaqueRegionBaseInfo_.screenRotation_ = screenRotation;
1483 opaqueRegionBaseInfo_.isFocusWindow_ = isFocusWindow;
1484 opaqueRegionBaseInfo_.cornerRadius_ = cornerRadius;
1485 opaqueRegionBaseInfo_.isTransparent_ = IsTransparent();
1486 opaqueRegionBaseInfo_.hasContainerWindow_ = HasContainerWindow();
1487 }
1488
1489 // [planning] Remove this after skia is upgraded, the clipRegion is supported
ResetChildrenFilterRects()1490 void RSSurfaceRenderNode::ResetChildrenFilterRects()
1491 {
1492 childrenFilterNodes_.clear();
1493 childrenFilterRects_.clear();
1494 childrenFilterRectsCacheValid_.clear();
1495 }
1496
UpdateChildrenFilterRects(std::shared_ptr<RSRenderNode> filternode,const RectI & rect,bool cacheValid)1497 void RSSurfaceRenderNode::UpdateChildrenFilterRects(std::shared_ptr<RSRenderNode> filternode,
1498 const RectI& rect, bool cacheValid)
1499 {
1500 if (!rect.IsEmpty()) {
1501 childrenFilterNodes_.emplace_back(filternode);
1502 childrenFilterRects_.emplace_back(rect);
1503 childrenFilterRectsCacheValid_.emplace_back(cacheValid);
1504 }
1505 }
1506
GetChildrenNeedFilterRects() const1507 const std::vector<RectI>& RSSurfaceRenderNode::GetChildrenNeedFilterRects() const
1508 {
1509 return childrenFilterRects_;
1510 }
1511
GetChildrenNeedFilterRectsCacheValid() const1512 const std::vector<bool>& RSSurfaceRenderNode::GetChildrenNeedFilterRectsCacheValid() const
1513 {
1514 return childrenFilterRectsCacheValid_;
1515 }
1516
GetChildrenFilterNodes() const1517 const std::vector<std::shared_ptr<RSRenderNode>>& RSSurfaceRenderNode::GetChildrenFilterNodes() const
1518 {
1519 return childrenFilterNodes_;
1520 }
1521
1522 // manage abilities' nodeid info
UpdateAbilityNodeIds(NodeId id,bool isAdded)1523 void RSSurfaceRenderNode::UpdateAbilityNodeIds(NodeId id, bool isAdded)
1524 {
1525 if (isAdded) {
1526 abilityNodeIds_.emplace(id);
1527 } else {
1528 abilityNodeIds_.erase(id);
1529 }
1530 }
1531
AddAbilityComponentNodeIds(std::unordered_set<NodeId> nodeIds)1532 void RSSurfaceRenderNode::AddAbilityComponentNodeIds(std::unordered_set<NodeId> nodeIds)
1533 {
1534 abilityNodeIds_.insert(nodeIds.begin(), nodeIds.end());
1535 }
1536
ResetAbilityNodeIds()1537 void RSSurfaceRenderNode::ResetAbilityNodeIds()
1538 {
1539 abilityNodeIds_.clear();
1540 }
1541
UpdateSurfaceCacheContentStatic(const std::unordered_map<NodeId,std::weak_ptr<RSRenderNode>> & activeNodeIds)1542 void RSSurfaceRenderNode::UpdateSurfaceCacheContentStatic(
1543 const std::unordered_map<NodeId, std::weak_ptr<RSRenderNode>>& activeNodeIds)
1544 {
1545 dirtyContentNodeNum_ = 0;
1546 dirtyGeoNodeNum_ = 0;
1547 dirtynodeNum_ = activeNodeIds.size();
1548 surfaceCacheContentStatic_ = IsOnlyBasicGeoTransform();
1549 if (dirtynodeNum_ == 0) {
1550 RS_LOGD("Clear surface %{public}" PRIu64 " dirtynodes surfaceCacheContentStatic_:%{public}d",
1551 GetId(), surfaceCacheContentStatic_);
1552 return;
1553 }
1554 for (auto [id, subNode] : activeNodeIds) {
1555 auto node = subNode.lock();
1556 if (node == nullptr || (id == GetId() && surfaceCacheContentStatic_)) {
1557 continue;
1558 }
1559 // classify active nodes except instance surface itself
1560 if (node->IsContentDirty() && !node->IsNewOnTree() && !node->GetRenderProperties().IsGeoDirty()) {
1561 dirtyContentNodeNum_++;
1562 } else {
1563 dirtyGeoNodeNum_++;
1564 }
1565 }
1566 // if mainwindow node only basicGeoTransform and no subnode dirty, it is marked as CacheContentStatic_
1567 surfaceCacheContentStatic_ = surfaceCacheContentStatic_ && dirtyContentNodeNum_ == 0 && dirtyGeoNodeNum_ == 0;
1568 }
1569
GetAbilityNodeIds() const1570 const std::unordered_set<NodeId>& RSSurfaceRenderNode::GetAbilityNodeIds() const
1571 {
1572 return abilityNodeIds_;
1573 }
1574
ResetChildHardwareEnabledNodes()1575 void RSSurfaceRenderNode::ResetChildHardwareEnabledNodes()
1576 {
1577 childHardwareEnabledNodes_.clear();
1578 }
1579
AddChildHardwareEnabledNode(std::weak_ptr<RSSurfaceRenderNode> childNode)1580 void RSSurfaceRenderNode::AddChildHardwareEnabledNode(std::weak_ptr<RSSurfaceRenderNode> childNode)
1581 {
1582 childHardwareEnabledNodes_.emplace_back(childNode);
1583 }
1584
GetChildHardwareEnabledNodes() const1585 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& RSSurfaceRenderNode::GetChildHardwareEnabledNodes() const
1586 {
1587 return childHardwareEnabledNodes_;
1588 }
1589
SetLocalZOrder(float localZOrder)1590 void RSSurfaceRenderNode::SetLocalZOrder(float localZOrder)
1591 {
1592 localZOrder_ = localZOrder;
1593 }
1594
GetLocalZOrder() const1595 float RSSurfaceRenderNode::GetLocalZOrder() const
1596 {
1597 return localZOrder_;
1598 }
1599
OnApplyModifiers()1600 void RSSurfaceRenderNode::OnApplyModifiers()
1601 {
1602 auto& properties = GetMutableRenderProperties();
1603 auto geoPtr = (properties.GetBoundsGeometry());
1604
1605 // Multiply context alpha into alpha
1606 properties.SetAlpha(properties.GetAlpha() * contextAlpha_);
1607
1608 // Apply the context matrix into the bounds geometry
1609 geoPtr->SetContextMatrix(contextMatrix_);
1610 if (!ShouldPaint()) {
1611 UpdateFilterCacheStatusWithVisible(false);
1612 }
1613 }
1614
1615 #ifndef USE_ROSEN_DRAWING
GetContextClipRegion() const1616 std::optional<SkRect> RSSurfaceRenderNode::GetContextClipRegion() const
1617 {
1618 return contextClipRect_;
1619 }
1620 #else
GetContextClipRegion() const1621 std::optional<Drawing::Rect> RSSurfaceRenderNode::GetContextClipRegion() const
1622 {
1623 return contextClipRect_;
1624 }
1625 #endif
1626
LeashWindowRelatedAppWindowOccluded(std::shared_ptr<RSSurfaceRenderNode> & appNode)1627 bool RSSurfaceRenderNode::LeashWindowRelatedAppWindowOccluded(std::shared_ptr<RSSurfaceRenderNode>& appNode)
1628 {
1629 if (!IsLeashWindow()) {
1630 return false;
1631 }
1632 for (auto& childNode : *GetChildren()) {
1633 const auto& childNodeSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(childNode);
1634 if (childNodeSurface && childNodeSurface->GetVisibleRegion().IsEmpty()) {
1635 appNode = childNodeSurface;
1636 return true;
1637 }
1638 }
1639 return false;
1640 }
1641
GetLeashWindowNestedSurfaces()1642 std::vector<std::shared_ptr<RSSurfaceRenderNode>> RSSurfaceRenderNode::GetLeashWindowNestedSurfaces()
1643 {
1644 std::vector<std::shared_ptr<RSSurfaceRenderNode>> res;
1645 if (!IsLeashWindow()) {
1646 return res;
1647 }
1648 for (auto& childNode : *GetSortedChildren()) {
1649 if (auto childNodeSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(childNode)) {
1650 res.emplace_back(childNodeSurface);
1651 }
1652 }
1653 return res;
1654 }
1655
IsHistoryOccludedDirtyRegionNeedSubmit()1656 bool RSSurfaceRenderNode::IsHistoryOccludedDirtyRegionNeedSubmit()
1657 {
1658 return (hasUnSubmittedOccludedDirtyRegion_ &&
1659 !historyUnSubmittedOccludedDirtyRegion_.IsEmpty() &&
1660 !visibleRegion_.IsEmpty() &&
1661 visibleRegion_.IsIntersectWith(historyUnSubmittedOccludedDirtyRegion_));
1662 }
1663
ClearHistoryUnSubmittedDirtyInfo()1664 void RSSurfaceRenderNode::ClearHistoryUnSubmittedDirtyInfo()
1665 {
1666 hasUnSubmittedOccludedDirtyRegion_ = false;
1667 historyUnSubmittedOccludedDirtyRegion_.Clear();
1668 }
1669
UpdateHistoryUnsubmittedDirtyInfo()1670 void RSSurfaceRenderNode::UpdateHistoryUnsubmittedDirtyInfo()
1671 {
1672 hasUnSubmittedOccludedDirtyRegion_ = true;
1673 historyUnSubmittedOccludedDirtyRegion_ = dirtyManager_->GetCurrentFrameDirtyRegion().JoinRect(
1674 historyUnSubmittedOccludedDirtyRegion_);
1675 }
1676
IsUIFirstSelfDrawCheck()1677 bool RSSurfaceRenderNode::IsUIFirstSelfDrawCheck()
1678 {
1679 if (IsAppWindow()) {
1680 auto hardwareEnabledNodes = GetChildHardwareEnabledNodes();
1681 for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
1682 auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
1683 if (hardwareEnabledNodePtr && hardwareEnabledNodePtr->IsCurrentFrameBufferConsumed()) {
1684 return false;
1685 }
1686 }
1687 }
1688 if (IsMainWindowType()) {
1689 return true;
1690 } else if (IsLeashWindow()) {
1691 auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1692 // leashwindow subthread cache considered static if and only if all nested surfacenode static
1693 // (include appwindow and starting window)
1694 for (auto& nestedSurface: nestedSurfaceNodes) {
1695 if (nestedSurface && !nestedSurface->IsUIFirstSelfDrawCheck()) {
1696 return false;
1697 }
1698 }
1699 return true;
1700 } else if (IsSelfDrawingType()) {
1701 return !isCurrentFrameBufferConsumed_;
1702 } else {
1703 return false;
1704 }
1705 }
1706
IsCurFrameStatic(DeviceType deviceType)1707 bool RSSurfaceRenderNode::IsCurFrameStatic(DeviceType deviceType)
1708 {
1709 bool isDirty = deviceType == DeviceType::PC ? !surfaceCacheContentStatic_ :
1710 (dirtyManager_ == nullptr || !dirtyManager_->GetCurrentFrameDirtyRegion().IsEmpty());
1711 if (isDirty) {
1712 return false;
1713 }
1714 if (IsMainWindowType()) {
1715 return true;
1716 } else if (IsLeashWindow()) {
1717 auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1718 // leashwindow children changed or has other type node except surfacenode
1719 if (deviceType == DeviceType::PC && lastFrameChildrenCnt_ != GetChildren()->size()) {
1720 return false;
1721 }
1722 for (auto& nestedSurface: nestedSurfaceNodes) {
1723 if (nestedSurface && !nestedSurface->IsCurFrameStatic(deviceType)) {
1724 return false;
1725 }
1726 }
1727 return true;
1728 } else {
1729 return false;
1730 }
1731 }
1732
IsVisibleDirtyEmpty(DeviceType deviceType)1733 bool RSSurfaceRenderNode::IsVisibleDirtyEmpty(DeviceType deviceType)
1734 {
1735 bool isStaticUnderVisibleRegion = false;
1736 if (dirtyManager_ == nullptr) {
1737 return false;
1738 }
1739 if (!dirtyManager_->GetCurrentFrameDirtyRegion().IsEmpty()) {
1740 if (deviceType != DeviceType::PC) {
1741 return false;
1742 }
1743 // Visible dirty region optimization takes effecct only in PC or TABLET scenarios
1744 Occlusion::Rect currentFrameDirty(dirtyManager_->GetCurrentFrameDirtyRegion());
1745 if (!visibleRegion_.IsEmpty() && visibleRegion_.IsIntersectWith(currentFrameDirty)) {
1746 ClearHistoryUnSubmittedDirtyInfo();
1747 return false;
1748 }
1749 isStaticUnderVisibleRegion = true;
1750 }
1751 if (IsMainWindowType()) {
1752 if (deviceType == DeviceType::PC) {
1753 if (IsHistoryOccludedDirtyRegionNeedSubmit()) {
1754 ClearHistoryUnSubmittedDirtyInfo();
1755 return false;
1756 }
1757 if (isStaticUnderVisibleRegion) {
1758 UpdateHistoryUnsubmittedDirtyInfo();
1759 }
1760 }
1761 return true;
1762 } else if (IsLeashWindow()) {
1763 auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1764 if (nestedSurfaceNodes.empty()) {
1765 return false;
1766 }
1767 for (auto& nestedSurface: nestedSurfaceNodes) {
1768 if (nestedSurface && !nestedSurface->IsVisibleDirtyEmpty(deviceType)) {
1769 return false;
1770 }
1771 }
1772 return true;
1773 } else {
1774 return false;
1775 }
1776 }
1777
IsUIFirstCacheReusable(DeviceType deviceType)1778 bool RSSurfaceRenderNode::IsUIFirstCacheReusable(DeviceType deviceType)
1779 {
1780 return GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DONE &&
1781 HasCachedTexture() && IsUIFirstSelfDrawCheck() && IsCurFrameStatic(deviceType);
1782 }
1783
UpdateCacheSurfaceDirtyManager(int bufferAge)1784 void RSSurfaceRenderNode::UpdateCacheSurfaceDirtyManager(int bufferAge)
1785 {
1786 if (!cacheSurfaceDirtyManager_ || !dirtyManager_) {
1787 return;
1788 }
1789 cacheSurfaceDirtyManager_->Clear();
1790 cacheSurfaceDirtyManager_->MergeDirtyRect(dirtyManager_->GetLatestDirtyRegion());
1791 cacheSurfaceDirtyManager_->SetBufferAge(bufferAge);
1792 cacheSurfaceDirtyManager_->UpdateDirty(false);
1793 // for leashwindow type, nested app surfacenode's cacheSurfaceDirtyManager update is required
1794 auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1795 for (auto& nestedSurface : nestedSurfaceNodes) {
1796 if (nestedSurface) {
1797 nestedSurface->UpdateCacheSurfaceDirtyManager(bufferAge);
1798 }
1799 }
1800 }
1801
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId)1802 void RSSurfaceRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
1803 NodeId cacheNodeId)
1804 {
1805 instanceRootNodeId = (IsMainWindowType() || IsLeashWindow()) ? GetId() : instanceRootNodeId;
1806 if (IsLeashWindow()) {
1807 firstLevelNodeId = GetId();
1808 } else if (IsAppWindow()) {
1809 firstLevelNodeId = GetId();
1810 auto parentNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(GetParent().lock());
1811 if (parentNode && parentNode->IsLeashWindow()) {
1812 firstLevelNodeId = parentNode->GetId();
1813 }
1814 }
1815 // if node is marked as cacheRoot, update subtree status when update surface
1816 // in case prepare stage upper cacheRoot cannot specify dirty subnode
1817 RSBaseRenderNode::SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId);
1818 }
1819
GetCacheSurfaceProcessedStatus() const1820 CacheProcessStatus RSSurfaceRenderNode::GetCacheSurfaceProcessedStatus() const
1821 {
1822 return cacheProcessStatus_.load();
1823 }
1824
SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)1825 void RSSurfaceRenderNode::SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)
1826 {
1827 cacheProcessStatus_.store(cacheProcessStatus);
1828 }
1829
HasOnlyOneRootNode() const1830 bool RSSurfaceRenderNode::HasOnlyOneRootNode() const
1831 {
1832 if (GetChildrenCount() != 1) {
1833 return false;
1834 }
1835
1836 const auto child = GetFirstChild();
1837 if (!child || child->GetType() != RSRenderNodeType::ROOT_NODE || child->GetChildrenCount() > 0) {
1838 return false;
1839 }
1840
1841 return true;
1842 }
1843
GetNodeIsSingleFrameComposer() const1844 bool RSSurfaceRenderNode::GetNodeIsSingleFrameComposer() const
1845 {
1846 bool flag = false;
1847 if (RSSystemProperties::GetSingleFrameComposerCanvasNodeEnabled()) {
1848 auto idx = GetName().find("hwstylusfeature");
1849 if (idx != std::string::npos) {
1850 flag = true;
1851 }
1852 }
1853 return isNodeSingleFrameComposer_ || flag;
1854 }
1855
QuerySubAssignable(bool isRotation)1856 bool RSSurfaceRenderNode::QuerySubAssignable(bool isRotation)
1857 {
1858 hasTransparentSurface_ = false;
1859 if (IsLeashWindow()) {
1860 for (auto &child : *GetSortedChildren()) {
1861 auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1862 if (childSurfaceNode && childSurfaceNode->IsTransparent()) {
1863 hasTransparentSurface_ = true;
1864 break;
1865 }
1866 }
1867 } else {
1868 hasTransparentSurface_ = IsTransparent();
1869 }
1870 return !(hasTransparentSurface_ && ChildHasFilter()) && !HasFilter() &&
1871 !HasAbilityComponent() && !isRotation && QueryIfAllHwcChildrenForceDisabledByFilter();
1872 }
1873
GetHasTransparentSurface() const1874 bool RSSurfaceRenderNode::GetHasTransparentSurface() const
1875 {
1876 return hasTransparentSurface_;
1877 }
1878
GetHasSharedTransitionNode() const1879 bool RSSurfaceRenderNode::GetHasSharedTransitionNode() const
1880 {
1881 return hasSharedTransitionNode_;
1882 }
1883
SetHasSharedTransitionNode(bool hasSharedTransitionNode)1884 void RSSurfaceRenderNode::SetHasSharedTransitionNode(bool hasSharedTransitionNode)
1885 {
1886 hasSharedTransitionNode_ = hasSharedTransitionNode;
1887 }
1888
GetGravityTranslate(float imgWidth,float imgHeight)1889 Vector2f RSSurfaceRenderNode::GetGravityTranslate(float imgWidth, float imgHeight)
1890 {
1891 Gravity gravity = GetRenderProperties().GetFrameGravity();
1892 if (IsLeashWindow()) {
1893 for (auto child : *GetSortedChildren()) {
1894 auto childSurfaceNode = child ? child->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1895 if (childSurfaceNode) {
1896 gravity = childSurfaceNode->GetRenderProperties().GetFrameGravity();
1897 break;
1898 }
1899 }
1900 }
1901
1902 float boundsWidth = GetRenderProperties().GetBoundsWidth();
1903 float boundsHeight = GetRenderProperties().GetBoundsHeight();
1904 #ifndef USE_ROSEN_DRAWING
1905 SkMatrix gravityMatrix;
1906 RSPropertiesPainter::GetGravityMatrix(gravity, RectF {0.0f, 0.0f, boundsWidth, boundsHeight},
1907 imgWidth, imgHeight, gravityMatrix);
1908 return {gravityMatrix.getTranslateX(), gravityMatrix.getTranslateY()};
1909 #else
1910 Drawing::Matrix gravityMatrix;
1911 RSPropertiesPainter::GetGravityMatrix(gravity, RectF {0.0f, 0.0f, boundsWidth, boundsHeight},
1912 imgWidth, imgHeight, gravityMatrix);
1913 return {gravityMatrix.Get(Drawing::Matrix::TRANS_X), gravityMatrix.Get(Drawing::Matrix::TRANS_Y)};
1914 #endif
1915 }
1916 } // namespace Rosen
1917 } // namespace OHOS
1918