• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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