• 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 "common/rs_obj_abs_geometry.h"
32 #include "common/rs_rect.h"
33 #include "common/rs_vector2.h"
34 #include "common/rs_vector4.h"
35 #include "ipc_callbacks/rs_rt_refresh_callback.h"
36 #include "pipeline/rs_render_node.h"
37 #include "pipeline/rs_root_render_node.h"
38 #include "platform/common/rs_log.h"
39 #include "platform/ohos/rs_jank_stats.h"
40 #include "property/rs_properties_painter.h"
41 #include "render/rs_skia_filter.h"
42 #include "transaction/rs_render_service_client.h"
43 #include "visitor/rs_node_visitor.h"
44 
45 namespace OHOS {
46 namespace Rosen {
RSSurfaceRenderNode(const RSSurfaceRenderNodeConfig & config,std::weak_ptr<RSContext> context)47 RSSurfaceRenderNode::RSSurfaceRenderNode(const RSSurfaceRenderNodeConfig& config, std::weak_ptr<RSContext> context)
48     : RSRenderNode(config.id, context),
49       RSSurfaceHandler(config.id),
50       name_(config.name),
51       bundleName_(config.bundleName),
52       nodeType_(config.nodeType),
53       dirtyManager_(std::make_shared<RSDirtyRegionManager>()),
54       cacheSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
55 {
56     MemoryInfo info = {sizeof(*this), ExtractPid(config.id), config.id, MEMORY_TYPE::MEM_RENDER_NODE};
57     MemoryTrack::Instance().AddNodeRecord(config.id, info);
58 }
59 
RSSurfaceRenderNode(NodeId id,std::weak_ptr<RSContext> context)60 RSSurfaceRenderNode::RSSurfaceRenderNode(NodeId id, std::weak_ptr<RSContext> context)
61     : RSSurfaceRenderNode(RSSurfaceRenderNodeConfig{id, "SurfaceNode"}, context)
62 {}
63 
~RSSurfaceRenderNode()64 RSSurfaceRenderNode::~RSSurfaceRenderNode()
65 {
66     MemoryTrack::Instance().RemoveNodeRecord(GetId());
67 }
68 
69 #ifndef ROSEN_CROSS_PLATFORM
SetConsumer(const sptr<IConsumerSurface> & consumer)70 void RSSurfaceRenderNode::SetConsumer(const sptr<IConsumerSurface>& consumer)
71 {
72     consumer_ = consumer;
73 }
74 #endif
75 
76 #ifndef USE_ROSEN_DRAWING
UpdateSrcRect(const RSPaintFilterCanvas & canvas,const SkIRect & dstRect)77 void RSSurfaceRenderNode::UpdateSrcRect(const RSPaintFilterCanvas& canvas, const SkIRect& dstRect)
78 {
79     auto localClipRect = RSPaintFilterCanvas::GetLocalClipBounds(canvas, &dstRect).value_or(SkRect::MakeEmpty());
80     const RSProperties& properties = GetRenderProperties();
81     int left = std::clamp<int>(localClipRect.left(), 0, properties.GetBoundsWidth());
82     int top = std::clamp<int>(localClipRect.top(), 0, properties.GetBoundsHeight());
83     int width = std::clamp<int>(localClipRect.width(), 0, properties.GetBoundsWidth() - left);
84     int height = std::clamp<int>(localClipRect.height(), 0, properties.GetBoundsHeight() - top);
85     RectI srcRect = {left, top, width, height};
86     SetSrcRect(srcRect);
87 }
88 #else
UpdateSrcRect(const RSPaintFilterCanvas & canvas,const Drawing::RectI & dstRect)89 void RSSurfaceRenderNode::UpdateSrcRect(const RSPaintFilterCanvas& canvas, const Drawing::RectI& dstRect)
90 {
91     auto localClipRect = RSPaintFilterCanvas::GetLocalClipBounds(canvas, &dstRect).value_or(Drawing::Rect());
92     const RSProperties& properties = GetRenderProperties();
93     int left = std::clamp<int>(localClipRect.GetLeft(), 0, properties.GetBoundsWidth());
94     int top = std::clamp<int>(localClipRect.GetTop(), 0, properties.GetBoundsHeight());
95     int width = std::clamp<int>(localClipRect.GetWidth(), 0, properties.GetBoundsWidth() - left);
96     int height = std::clamp<int>(localClipRect.GetHeight(), 0, properties.GetBoundsHeight() - top);
97     RectI srcRect = {left, top, width, height};
98     SetSrcRect(srcRect);
99 }
100 #endif
101 
ShouldPrepareSubnodes()102 bool RSSurfaceRenderNode::ShouldPrepareSubnodes()
103 {
104     // if a appwindow or abilitycomponent has a empty dstrect, its subnodes' prepare stage can be skipped
105     // most common scenario: HiBoard (SwipeLeft screen on home screen)
106     if (GetDstRect().IsEmpty() && (IsAppWindow() || IsAbilityComponent())) {
107         return false;
108     }
109     return true;
110 }
111 
DirtyRegionDump() const112 std::string RSSurfaceRenderNode::DirtyRegionDump() const
113 {
114     std::string dump = GetName() +
115         " SurfaceNodeType [" + std::to_string(static_cast<unsigned int>(GetSurfaceNodeType())) + "]" +
116         " Transparent [" + std::to_string(IsTransparent()) +"]" +
117         " DstRect: " + GetDstRect().ToString() +
118         " VisibleRegion: " + GetVisibleRegion().GetRegionInfo() +
119         " VisibleDirtyRegion: " + GetVisibleDirtyRegion().GetRegionInfo() +
120         " GlobalDirtyRegion: " + GetGlobalDirtyRegion().GetRegionInfo();
121     if (GetDirtyManager()) {
122         dump += " DirtyRegion: " + GetDirtyManager()->GetDirtyRegion().ToString();
123     }
124     return dump;
125 }
126 
PrepareRenderBeforeChildren(RSPaintFilterCanvas & canvas)127 void RSSurfaceRenderNode::PrepareRenderBeforeChildren(RSPaintFilterCanvas& canvas)
128 {
129     // Save the current state of the canvas before modifying it.
130 #ifndef USE_ROSEN_DRAWING
131     renderNodeSaveCount_ = canvas.Save();
132 #else
133     renderNodeSaveCount_ = canvas.SaveAllStatus();
134 #endif
135 
136     // Apply alpha to canvas
137     const RSProperties& properties = GetRenderProperties();
138     canvas.MultiplyAlpha(properties.GetAlpha());
139 
140     // Apply matrix to canvas
141     auto currentGeoPtr = (properties.GetBoundsGeometry());
142     if (currentGeoPtr != nullptr) {
143         currentGeoPtr->UpdateByMatrixFromSelf();
144         auto matrix = currentGeoPtr->GetMatrix();
145 #ifndef USE_ROSEN_DRAWING
146         matrix.setTranslateX(std::ceil(matrix.getTranslateX()));
147         matrix.setTranslateY(std::ceil(matrix.getTranslateY()));
148         canvas.concat(matrix);
149 #else
150         matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X)));
151         matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y)));
152         canvas.ConcatMatrix(matrix);
153 #endif
154     }
155 
156     // Clip by bounds
157 #ifndef USE_ROSEN_DRAWING
158     canvas.clipRect(SkRect::MakeWH(std::floor(properties.GetBoundsWidth()), std::floor(properties.GetBoundsHeight())));
159 
160     // Extract srcDest and dstRect from SkCanvas, localCLipBounds as SrcRect, deviceClipBounds as DstRect
161     auto deviceClipRect = canvas.getDeviceClipBounds();
162     UpdateSrcRect(canvas, deviceClipRect);
163     RectI dstRect = { deviceClipRect.left(), deviceClipRect.top(), deviceClipRect.width(), deviceClipRect.height() };
164     SetDstRect(dstRect);
165 
166     // Save TotalMatrix and GlobalAlpha for compositor
167     SetTotalMatrix(canvas.getTotalMatrix());
168 #else
169     canvas.ClipRect(Drawing::Rect(0, 0, std::floor(properties.GetBoundsWidth()),
170         std::floor(properties.GetBoundsHeight())), Drawing::ClipOp::INTERSECT, false);
171 
172     // Extract srcDest and dstRect from Drawing::Canvas, localCLipBounds as SrcRect, deviceClipBounds as DstRect
173     auto deviceClipRect = canvas.GetDeviceClipBounds();
174     UpdateSrcRect(canvas, deviceClipRect);
175     RectI dstRect = {
176         deviceClipRect.GetLeft(), deviceClipRect.GetTop(), deviceClipRect.GetWidth(), deviceClipRect.GetHeight() };
177     SetDstRect(dstRect);
178 
179     // Save TotalMatrix and GlobalAlpha for compositor
180     SetTotalMatrix(canvas.GetTotalMatrix());
181 #endif
182     SetGlobalAlpha(canvas.GetAlpha());
183 }
184 
PrepareRenderAfterChildren(RSPaintFilterCanvas & canvas)185 void RSSurfaceRenderNode::PrepareRenderAfterChildren(RSPaintFilterCanvas& canvas)
186 {
187     canvas.RestoreStatus(renderNodeSaveCount_);
188 }
189 
CollectSurface(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<RSBaseRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)190 void RSSurfaceRenderNode::CollectSurface(
191     const std::shared_ptr<RSBaseRenderNode>& node, std::vector<RSBaseRenderNode::SharedPtr>& vec, bool isUniRender,
192     bool onlyFirstLevel)
193 {
194     if (IsStartingWindow()) {
195         if (isUniRender) {
196             vec.emplace_back(shared_from_this());
197         }
198         return;
199     }
200     if (IsLeashWindow()) {
201         if (isUniRender) {
202             vec.emplace_back(shared_from_this());
203         }
204         if (onlyFirstLevel) {
205             return;
206         }
207         for (auto& child : node->GetSortedChildren()) {
208             child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
209         }
210         return;
211     }
212 
213 #ifndef ROSEN_CROSS_PLATFORM
214     auto& consumer = GetConsumer();
215     if (consumer != nullptr && consumer->GetTunnelHandle() != nullptr) {
216         return;
217     }
218 #endif
219     auto num = find(vec.begin(), vec.end(), shared_from_this());
220     if (num != vec.end()) {
221         return;
222     }
223     if (isUniRender && ShouldPaint()) {
224         vec.emplace_back(shared_from_this());
225     } else {
226 #ifndef ROSEN_CROSS_PLATFORM
227         if (GetBuffer() != nullptr && ShouldPaint()) {
228             vec.emplace_back(shared_from_this());
229         }
230 #endif
231     }
232 }
233 
ClearChildrenCache(const std::shared_ptr<RSBaseRenderNode> & node)234 void RSSurfaceRenderNode::ClearChildrenCache(const std::shared_ptr<RSBaseRenderNode>& node)
235 {
236     for (auto& child : node->GetChildren()) {
237         auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>();
238         if (surfaceNode == nullptr) {
239             continue;
240         }
241 #ifndef ROSEN_CROSS_PLATFORM
242         auto& consumer = surfaceNode->GetConsumer();
243         if (consumer != nullptr) {
244             consumer->GoBackground();
245         }
246 #endif
247     }
248 }
249 
OnTreeStateChanged()250 void RSSurfaceRenderNode::OnTreeStateChanged()
251 {
252 #ifdef RS_ENABLE_GL
253     RSRenderNode::OnTreeStateChanged();
254     if (grContext_ && !IsOnTheTree() && IsLeashWindow()) {
255 #ifndef USE_ROSEN_DRAWING
256         RS_TRACE_NAME_FMT("purgeUnlockedResources this SurfaceNode isn't on the tree Id:%" PRIu64 " Name:%s",
257             GetId(), GetName().c_str());
258         grContext_->purgeUnlockedResources(true);
259 #endif
260     }
261 #endif
262 }
263 
OnResetParent()264 void RSSurfaceRenderNode::OnResetParent()
265 {
266     if (nodeType_ == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
267         ClearChildrenCache(shared_from_this());
268     } else {
269 #ifndef ROSEN_CROSS_PLATFORM
270         auto& consumer = GetConsumer();
271         if (consumer != nullptr && !IsSelfDrawingType() && !IsAbilityComponent()) {
272             consumer->GoBackground();
273         }
274 #endif
275     }
276 }
277 
SetIsNotifyUIBufferAvailable(bool available)278 void RSSurfaceRenderNode::SetIsNotifyUIBufferAvailable(bool available)
279 {
280     isNotifyUIBufferAvailable_.store(available);
281 }
282 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)283 void RSSurfaceRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
284 {
285     if (!visitor) {
286         return;
287     }
288     visitor->PrepareSurfaceRenderNode(*this);
289 }
290 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)291 void RSSurfaceRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
292 {
293     if (!visitor) {
294         return;
295     }
296     RSRenderNode::RenderTraceDebug();
297     visitor->ProcessSurfaceRenderNode(*this);
298 }
299 
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)300 void RSSurfaceRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
301 {
302     needDrawAnimateProperty_ = true;
303     ProcessAnimatePropertyBeforeChildren(canvas);
304     needDrawAnimateProperty_ = false;
305 }
306 
ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas & canvas)307 void RSSurfaceRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas& canvas)
308 {
309     if (GetCacheType() != CacheType::ANIMATE_PROPERTY && !needDrawAnimateProperty_) {
310         return;
311     }
312     const auto& property = GetRenderProperties();
313     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
314     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
315     RSPropertiesPainter::DrawShadow(property, canvas, &absClipRRect, IsLeashWindow());
316 
317 #ifndef USE_ROSEN_DRAWING
318     if (!property.GetCornerRadius().IsZero()) {
319         canvas.clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
320     } else {
321         canvas.clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
322     }
323 #else
324     if (!property.GetCornerRadius().IsZero()) {
325         canvas.ClipRoundRect(
326             RSPropertiesPainter::RRect2DrawingRRect(absClipRRect), Drawing::ClipOp::INTERSECT, true);
327     } else {
328         canvas.ClipRect(Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()),
329             Drawing::ClipOp::INTERSECT, false);
330     }
331 #endif
332 
333     RSPropertiesPainter::DrawBackground(property, canvas);
334     RSPropertiesPainter::DrawMask(property, canvas);
335     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::BACKGROUND_FILTER);
336 #ifndef USE_ROSEN_DRAWING
337     SetTotalMatrix(canvas.getTotalMatrix());
338 #else
339     SetTotalMatrix(canvas.GetTotalMatrix());
340 #endif
341 }
342 
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)343 void RSSurfaceRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
344 {
345     needDrawAnimateProperty_ = true;
346     ProcessAnimatePropertyAfterChildren(canvas);
347     needDrawAnimateProperty_ = false;
348 }
349 
ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas & canvas)350 void RSSurfaceRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas& canvas)
351 {
352     if (GetCacheType() != CacheType::ANIMATE_PROPERTY && !needDrawAnimateProperty_) {
353         return;
354     }
355     const auto& property = GetRenderProperties();
356     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::FOREGROUND_FILTER);
357     RSPropertiesPainter::DrawLinearGradientBlurFilter(property, canvas);
358 #ifndef USE_ROSEN_DRAWING
359     canvas.save();
360     if (GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE) {
361         auto geoPtr = (property.GetBoundsGeometry());
362         canvas.concat(geoPtr->GetMatrix());
363     }
364     RSPropertiesPainter::DrawBorder(property, canvas);
365     canvas.restore();
366 #else
367     canvas.Save();
368     if (GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE) {
369         auto geoPtr = (property.GetBoundsGeometry());
370         canvas.ConcatMatrix(geoPtr->GetMatrix());
371     }
372     RSPropertiesPainter::DrawBorder(property, canvas);
373     canvas.Restore();
374 #endif
375 }
376 
SetContextBounds(const Vector4f bounds)377 void RSSurfaceRenderNode::SetContextBounds(const Vector4f bounds)
378 {
379     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetBounds>(GetId(), bounds);
380     SendCommandFromRT(command, GetId());
381 }
382 
GetDirtyManager() const383 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNode::GetDirtyManager() const
384 {
385     return dirtyManager_;
386 }
387 
GetCacheSurfaceDirtyManager() const388 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNode::GetCacheSurfaceDirtyManager() const
389 {
390     return cacheSurfaceDirtyManager_;
391 }
392 
MarkUIHidden(bool isHidden)393 void RSSurfaceRenderNode::MarkUIHidden(bool isHidden)
394 {
395     isUIHidden_ = isHidden;
396 }
397 
IsUIHidden() const398 bool RSSurfaceRenderNode::IsUIHidden() const
399 {
400     return isUIHidden_;
401 }
402 
403 #ifndef USE_ROSEN_DRAWING
SetContextMatrix(const std::optional<SkMatrix> & matrix,bool sendMsg)404 void RSSurfaceRenderNode::SetContextMatrix(const std::optional<SkMatrix>& matrix, bool sendMsg)
405 #else
406 void RSSurfaceRenderNode::SetContextMatrix(const std::optional<Drawing::Matrix>& matrix, bool sendMsg)
407 #endif
408 {
409     if (contextMatrix_ == matrix) {
410         return;
411     }
412     contextMatrix_ = matrix;
413     SetContentDirty();
414     AddDirtyType(RSModifierType::SCALE);
415     AddDirtyType(RSModifierType::TRANSLATE);
416     if (!sendMsg) {
417         return;
418     }
419     // send a Command
420     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextMatrix>(GetId(), matrix);
421     SendCommandFromRT(command, GetId());
422 }
423 
SetContextAlpha(float alpha,bool sendMsg)424 void RSSurfaceRenderNode::SetContextAlpha(float alpha, bool sendMsg)
425 {
426     if (contextAlpha_ == alpha) {
427         return;
428     }
429     contextAlpha_ = alpha;
430     SetContentDirty();
431     AddDirtyType(RSModifierType::ALPHA);
432     if (!sendMsg) {
433         return;
434     }
435     // send a Command
436     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextAlpha>(GetId(), alpha);
437     SendCommandFromRT(command, GetId());
438 }
439 
440 #ifndef USE_ROSEN_DRAWING
SetContextClipRegion(const std::optional<SkRect> & clipRegion,bool sendMsg)441 void RSSurfaceRenderNode::SetContextClipRegion(const std::optional<SkRect>& clipRegion, bool sendMsg)
442 #else
443 void RSSurfaceRenderNode::SetContextClipRegion(const std::optional<Drawing::Rect>& clipRegion, bool sendMsg)
444 #endif
445 {
446     if (contextClipRect_ == clipRegion) {
447         return;
448     }
449     contextClipRect_ = clipRegion;
450     SetContentDirty();
451     AddDirtyType(RSModifierType::BOUNDS);
452     if (!sendMsg) {
453         return;
454     }
455     // send a Command
456     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextClipRegion>(GetId(), clipRegion);
457     SendCommandFromRT(command, GetId());
458 }
459 
SetSecurityLayer(bool isSecurityLayer)460 void RSSurfaceRenderNode::SetSecurityLayer(bool isSecurityLayer)
461 {
462     isSecurityLayer_ = isSecurityLayer;
463 }
464 
GetSecurityLayer() const465 bool RSSurfaceRenderNode::GetSecurityLayer() const
466 {
467     return isSecurityLayer_;
468 }
469 
SetFingerprint(bool hasFingerprint)470 void RSSurfaceRenderNode::SetFingerprint(bool hasFingerprint)
471 {
472     hasFingerprint_ = hasFingerprint;
473 }
474 
GetFingerprint() const475 bool RSSurfaceRenderNode::GetFingerprint() const
476 {
477     return hasFingerprint_;
478 }
479 
480 #ifndef ROSEN_CROSS_PLATFORM
SetColorSpace(GraphicColorGamut colorSpace)481 void RSSurfaceRenderNode::SetColorSpace(GraphicColorGamut colorSpace)
482 {
483     colorSpace_ = colorSpace;
484 }
485 
GetColorSpace() const486 GraphicColorGamut RSSurfaceRenderNode::GetColorSpace() const
487 {
488     return colorSpace_;
489 }
490 #endif
491 
UpdateSurfaceDefaultSize(float width,float height)492 void RSSurfaceRenderNode::UpdateSurfaceDefaultSize(float width, float height)
493 {
494 #ifndef ROSEN_CROSS_PLATFORM
495     if (consumer_ != nullptr) {
496         consumer_->SetDefaultWidthAndHeight(width, height);
497     }
498 #endif
499 }
500 
501 #ifndef ROSEN_CROSS_PLATFORM
GetBlendType()502 GraphicBlendType RSSurfaceRenderNode::GetBlendType()
503 {
504     return blendType_;
505 }
506 
SetBlendType(GraphicBlendType blendType)507 void RSSurfaceRenderNode::SetBlendType(GraphicBlendType blendType)
508 {
509     blendType_ = blendType;
510 }
511 #endif
512 
RegisterBufferAvailableListener(sptr<RSIBufferAvailableCallback> callback,bool isFromRenderThread)513 void RSSurfaceRenderNode::RegisterBufferAvailableListener(
514     sptr<RSIBufferAvailableCallback> callback, bool isFromRenderThread)
515 {
516     if (isFromRenderThread) {
517         std::lock_guard<std::mutex> lock(mutexRT_);
518         callbackFromRT_ = callback;
519     } else {
520         {
521             std::lock_guard<std::mutex> lock(mutexUI_);
522             callbackFromUI_ = callback;
523         }
524         isNotifyUIBufferAvailable_ = false;
525     }
526 }
527 
RegisterBufferClearListener(sptr<RSIBufferClearCallback> callback)528 void RSSurfaceRenderNode::RegisterBufferClearListener(
529     sptr<RSIBufferClearCallback> callback)
530 {
531     std::lock_guard<std::mutex> lock(mutexClear_);
532     clearBufferCallback_ = callback;
533 }
534 
SetNotifyRTBufferAvailable(bool isNotifyRTBufferAvailable)535 void RSSurfaceRenderNode::SetNotifyRTBufferAvailable(bool isNotifyRTBufferAvailable)
536 {
537     isNotifyRTBufferAvailable_ = isNotifyRTBufferAvailable;
538     std::lock_guard<std::mutex> lock(mutexClear_);
539     if (clearBufferCallback_) {
540         clearBufferCallback_->OnBufferClear();
541     }
542 }
543 
ConnectToNodeInRenderService()544 void RSSurfaceRenderNode::ConnectToNodeInRenderService()
545 {
546     ROSEN_LOGI("RSSurfaceRenderNode::ConnectToNodeInRenderService nodeId = %" PRIu64, GetId());
547     auto renderServiceClient =
548         std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
549     if (renderServiceClient != nullptr) {
550         renderServiceClient->RegisterBufferAvailableListener(
551             GetId(), [weakThis = weak_from_this()]() {
552                 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(weakThis.lock());
553                 if (node == nullptr) {
554                     return;
555                 }
556                 node->NotifyRTBufferAvailable();
557             }, true);
558         renderServiceClient->RegisterBufferClearListener(
559             GetId(), [weakThis = weak_from_this()]() {
560                 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(weakThis.lock());
561                 if (node == nullptr) {
562                     return;
563                 }
564                 node->SetNotifyRTBufferAvailable(false);
565             });
566     }
567 }
568 
NotifyRTBufferAvailable()569 void RSSurfaceRenderNode::NotifyRTBufferAvailable()
570 {
571     // In RS, "isNotifyRTBufferAvailable_ = true" means buffer is ready and need to trigger ipc callback.
572     // In RT, "isNotifyRTBufferAvailable_ = true" means RT know that RS have had available buffer
573     // and ready to trigger "callbackForRenderThreadRefresh_" to "clip" on parent surface.
574     isNotifyRTBufferAvailablePre_ = isNotifyRTBufferAvailable_;
575     if (isNotifyRTBufferAvailable_) {
576         return;
577     }
578     isNotifyRTBufferAvailable_ = true;
579 
580     if (isRefresh_) {
581         ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %" PRIu64 " RenderThread", GetId());
582         RSRTRefreshCallback::Instance().ExcuteRefresh();
583     }
584 
585     {
586         std::lock_guard<std::mutex> lock(mutexRT_);
587         if (callbackFromRT_) {
588             ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %" PRIu64 " RenderService", GetId());
589             callbackFromRT_->OnBufferAvailable();
590         }
591         if (!isRefresh_ && !callbackFromRT_) {
592             isNotifyRTBufferAvailable_ = false;
593         }
594     }
595 }
596 
NotifyUIBufferAvailable()597 void RSSurfaceRenderNode::NotifyUIBufferAvailable()
598 {
599     if (isNotifyUIBufferAvailable_) {
600         return;
601     }
602     isNotifyUIBufferAvailable_ = true;
603     {
604         std::lock_guard<std::mutex> lock(mutexUI_);
605         if (callbackFromUI_) {
606             ROSEN_LOGD("RSSurfaceRenderNode::NotifyUIBufferAvailable nodeId = %" PRIu64, GetId());
607             callbackFromUI_->OnBufferAvailable();
608         }
609     }
610 }
611 
IsNotifyRTBufferAvailable() const612 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailable() const
613 {
614 #if defined(ROSEN_ANDROID) || defined(ROSEN_IOS)
615     return true;
616 #else
617     return isNotifyRTBufferAvailable_;
618 #endif
619 }
620 
IsNotifyRTBufferAvailablePre() const621 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailablePre() const
622 {
623 #if defined(ROSEN_ANDROID) || defined(ROSEN_IOS)
624     return true;
625 #else
626     return isNotifyRTBufferAvailablePre_;
627 #endif
628 }
629 
IsNotifyUIBufferAvailable() const630 bool RSSurfaceRenderNode::IsNotifyUIBufferAvailable() const
631 {
632     return isNotifyUIBufferAvailable_;
633 }
634 
SetCallbackForRenderThreadRefresh(bool isRefresh)635 void RSSurfaceRenderNode::SetCallbackForRenderThreadRefresh(bool isRefresh)
636 {
637     isRefresh_ = isRefresh;
638 }
639 
NeedSetCallbackForRenderThreadRefresh()640 bool RSSurfaceRenderNode::NeedSetCallbackForRenderThreadRefresh()
641 {
642     return !isRefresh_;
643 }
644 
IsStartAnimationFinished() const645 bool RSSurfaceRenderNode::IsStartAnimationFinished() const
646 {
647     return startAnimationFinished_;
648 }
649 
SetStartAnimationFinished()650 void RSSurfaceRenderNode::SetStartAnimationFinished()
651 {
652     RS_LOGD("RSSurfaceRenderNode::SetStartAnimationFinished");
653     startAnimationFinished_ = true;
654 }
655 
UpdateDirtyIfFrameBufferConsumed()656 bool RSSurfaceRenderNode::UpdateDirtyIfFrameBufferConsumed()
657 {
658     if (isCurrentFrameBufferConsumed_) {
659         SetContentDirty();
660         return true;
661     }
662     return false;
663 }
664 
SetVisibleRegionRecursive(const Occlusion::Region & region,VisibleData & visibleVec,std::map<uint32_t,bool> & pidVisMap)665 void RSSurfaceRenderNode::SetVisibleRegionRecursive(const Occlusion::Region& region,
666                                                     VisibleData& visibleVec,
667                                                     std::map<uint32_t, bool>& pidVisMap)
668 {
669     if (nodeType_ == RSSurfaceNodeType::SELF_DRAWING_NODE || IsAbilityComponent()) {
670         SetOcclusionVisible(true);
671         visibleVec.emplace_back(GetId());
672         return;
673     }
674     visibleRegion_ = region;
675     bool vis = region.GetSize() > 0;
676     if (vis) {
677         visibleVec.emplace_back(GetId());
678     }
679 
680     // collect visible changed pid
681     if (qosPidCal_ && GetType() == RSRenderNodeType::SURFACE_NODE) {
682         uint32_t tmpPid = ExtractPid(GetId());
683         if (pidVisMap.find(tmpPid) != pidVisMap.end()) {
684             pidVisMap[tmpPid] |= vis;
685         } else {
686             pidVisMap[tmpPid] = vis;
687         }
688     }
689 
690     SetOcclusionVisible(vis);
691     for (auto& child : GetChildren()) {
692         if (auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)) {
693             surface->SetVisibleRegionRecursive(region, visibleVec, pidVisMap);
694         }
695     }
696 }
697 
SubNodeIntersectWithExtraDirtyRegion(const RectI & r) const698 bool RSSurfaceRenderNode::SubNodeIntersectWithExtraDirtyRegion(const RectI& r) const
699 {
700     if (!isDirtyRegionAlignedEnable_) {
701         return false;
702     }
703     if (!extraDirtyRegionAfterAlignmentIsEmpty_) {
704         return extraDirtyRegionAfterAlignment_.IsIntersectWith(r);
705     }
706     return false;
707 }
708 
SubNodeIntersectWithDirty(const RectI & r) const709 bool RSSurfaceRenderNode::SubNodeIntersectWithDirty(const RectI& r) const
710 {
711     Occlusion::Rect nodeRect { r.left_, r.top_, r.GetRight(), r.GetBottom() };
712     // if current node rect r is in global dirtyregion, it CANNOT be skipped
713     if (!globalDirtyRegionIsEmpty_) {
714         auto globalRect = globalDirtyRegion_.IsIntersectWith(nodeRect);
715         if (globalRect) {
716             return true;
717         }
718     }
719     // if current node is in visible dirtyRegion, it CANNOT be skipped
720     bool localIntersect = visibleDirtyRegion_.IsIntersectWith(nodeRect);
721     if (localIntersect) {
722         return true;
723     }
724     // if current node is transparent
725     if (IsTransparent() || IsCurrentNodeInTransparentRegion(nodeRect)) {
726         return dirtyRegionBelowCurrentLayer_.IsIntersectWith(nodeRect);
727     }
728     return false;
729 }
730 
SubNodeNeedDraw(const RectI & r,PartialRenderType opDropType) const731 bool RSSurfaceRenderNode::SubNodeNeedDraw(const RectI &r, PartialRenderType opDropType) const
732 {
733     if (dirtyManager_ == nullptr) {
734         return true;
735     }
736     switch (opDropType) {
737         case PartialRenderType::SET_DAMAGE_AND_DROP_OP:
738             return SubNodeIntersectWithDirty(r);
739         case PartialRenderType::SET_DAMAGE_AND_DROP_OP_OCCLUSION:
740             return SubNodeVisible(r);
741         case PartialRenderType::SET_DAMAGE_AND_DROP_OP_NOT_VISIBLEDIRTY:
742             // intersect with self visible dirty or other surfaces' extra dirty region after alignment
743             return SubNodeVisible(r) && (SubNodeIntersectWithDirty(r) ||
744                 SubNodeIntersectWithExtraDirtyRegion(r));
745         case PartialRenderType::DISABLED:
746         case PartialRenderType::SET_DAMAGE:
747         default:
748             return true;
749     }
750     return true;
751 }
752 
ResetSurfaceOpaqueRegion(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow)753 void RSSurfaceRenderNode::ResetSurfaceOpaqueRegion(const RectI& screeninfo, const RectI& absRect,
754     const ScreenRotation screenRotation, const bool isFocusWindow)
755 {
756     Occlusion::Rect absRectR {absRect};
757     Occlusion::Region oldOpaqueRegion { opaqueRegion_ };
758 
759     // The transparent region of surfaceNode should include shadow area
760     Occlusion::Rect dirtyRect {GetOldDirty()};
761     transparentRegion_ = Occlusion::Region{dirtyRect};
762 
763     if (IsTransparent()) {
764         opaqueRegion_ = Occlusion::Region();
765     } else {
766         if (IsAppWindow() && HasContainerWindow()) {
767             opaqueRegion_ = ResetOpaqueRegion(absRect, screenRotation, isFocusWindow);
768         } else {
769             auto corner = GetWindowCornerRadius();
770             if (!corner.IsZero()) {
771                 opaqueRegion_ = SetCornerRadiusOpaqueRegion(absRect, std::ceil(corner.x_));
772             } else {
773                 opaqueRegion_ = Occlusion::Region{absRectR};
774             }
775         }
776         transparentRegion_.SubSelf(opaqueRegion_);
777     }
778     Occlusion::Rect screen{screeninfo};
779     Occlusion::Region screenRegion{screen};
780     transparentRegion_.AndSelf(screenRegion);
781     opaqueRegion_.AndSelf(screenRegion);
782     opaqueRegionChanged_ = !oldOpaqueRegion.Xor(opaqueRegion_).IsEmpty();
783     ResetSurfaceContainerRegion(screeninfo, absRect, screenRotation);
784 }
785 
UpdateFilterNodes(const std::shared_ptr<RSRenderNode> & nodePtr)786 void RSSurfaceRenderNode::UpdateFilterNodes(const std::shared_ptr<RSRenderNode>& nodePtr)
787 {
788     if (nodePtr == nullptr) {
789         return;
790     }
791     filterNodes_.emplace(nodePtr->GetId(), nodePtr);
792 }
793 
UpdateFilterCacheStatusIfNodeStatic(const RectI & clipRect)794 void RSSurfaceRenderNode::UpdateFilterCacheStatusIfNodeStatic(const RectI& clipRect)
795 {
796     if (!dirtyManager_) {
797         return;
798     }
799 #ifndef USE_ROSEN_DRAWING
800     // traversal filter nodes including app window
801     EraseIf(filterNodes_, [this](const auto& pair) {
802         auto& node = pair.second;
803         if (node == nullptr || !node->IsOnTheTree() || !node->GetRenderProperties().NeedFilter()) {
804             return true;
805         }
806         node->UpdateFilterCacheWithDirty(*dirtyManager_, false);
807         node->UpdateFilterCacheWithDirty(*dirtyManager_, true);
808         // collect valid filter nodes for occlusion optimization
809         if (node->IsFilterCacheValid()) {
810             dirtyManager_->UpdateCacheableFilterRect(node->GetOldDirtyInSurface());
811         }
812         return false;
813     });
814     if (IsTransparent() && dirtyManager_->IfCacheableFilterRectFullyCover(GetOldDirtyInSurface())) {
815         SetFilterCacheFullyCovered(true);
816         RS_LOGD("UpdateFilterCacheStatusIfNodeStatic surfacenode %" PRIu64 " [%s]", GetId(), GetName().c_str());
817     }
818 #endif
819 }
820 
GetWindowCornerRadius()821 Vector4f RSSurfaceRenderNode::GetWindowCornerRadius()
822 {
823     if (!GetRenderProperties().GetCornerRadius().IsZero()) {
824         return GetRenderProperties().GetCornerRadius();
825     }
826     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(GetParent().lock());
827     if (parent != nullptr && parent->IsLeashWindow()) {
828         return parent->GetRenderProperties().GetCornerRadius();
829     }
830     return Vector4f();
831 }
832 
ResetOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow) const833 Occlusion::Region RSSurfaceRenderNode::ResetOpaqueRegion(const RectI& absRect,
834     const ScreenRotation screenRotation, const bool isFocusWindow) const
835 {
836     if (isFocusWindow) {
837         return SetFocusedWindowOpaqueRegion(absRect, screenRotation);
838     } else {
839         return SetUnfocusedWindowOpaqueRegion(absRect, screenRotation);
840     }
841 }
842 
Update(bool hasContainer,float density)843 void RSSurfaceRenderNode::ContainerConfig::Update(bool hasContainer, float density)
844 {
845     this->hasContainerWindow_ = hasContainer;
846     this->density = density;
847 
848     // px = vp * density
849     float containerTitleHeight_ = CONTAINER_TITLE_HEIGHT * density;
850     float containerContentPadding_ = CONTENT_PADDING * density;
851     float containerBorderWidth_ = CONTAINER_BORDER_WIDTH * density;
852     float containerOutRadius_ = CONTAINER_OUTER_RADIUS * density;
853     float containerInnerRadius_ = CONTAINER_INNER_RADIUS * density;
854 
855     this->outR = RoundFloor(containerOutRadius_);
856     this->inR = RoundFloor(containerInnerRadius_);
857     this->bp = RoundFloor(containerBorderWidth_ + containerContentPadding_);
858     this->bt = RoundFloor(containerBorderWidth_ + containerTitleHeight_);
859 }
860 
861 /*
862     If a surfacenode with containerwindow is not focus window, then its opaque
863 region is absRect minus four roundCorner corresponding small rectangles.
864 This corners removed region can be assembled with two crossed rectangles.
865 Furthermore, when the surfacenode is not focus window, the inner content roundrect's
866 boundingbox rect can be set opaque.
867 */
SetUnfocusedWindowOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation) const868 Occlusion::Region RSSurfaceRenderNode::SetUnfocusedWindowOpaqueRegion(const RectI& absRect,
869     const ScreenRotation screenRotation) const
870 {
871     Occlusion::Rect opaqueRect1{ absRect.left_ + containerConfig_.outR,
872         absRect.top_,
873         absRect.GetRight() - containerConfig_.outR,
874         absRect.GetBottom()};
875     Occlusion::Rect opaqueRect2{ absRect.left_,
876         absRect.top_ + containerConfig_.outR,
877         absRect.GetRight(),
878         absRect.GetBottom() - containerConfig_.outR};
879     Occlusion::Region r1{opaqueRect1};
880     Occlusion::Region r2{opaqueRect2};
881     Occlusion::Region opaqueRegion = r1.Or(r2);
882 
883     switch (screenRotation) {
884         case ScreenRotation::ROTATION_0: {
885             Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
886                 absRect.top_ + containerConfig_.bt,
887                 absRect.GetRight() - containerConfig_.bp,
888                 absRect.GetBottom() - containerConfig_.bp};
889             Occlusion::Region r3{opaqueRect3};
890             opaqueRegion.OrSelf(r3);
891             break;
892         }
893         case ScreenRotation::ROTATION_90: {
894             Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bt,
895                 absRect.top_ + containerConfig_.bp,
896                 absRect.GetRight() - containerConfig_.bp,
897                 absRect.GetBottom() - containerConfig_.bp};
898             Occlusion::Region r3{opaqueRect3};
899             opaqueRegion.OrSelf(r3);
900             break;
901         }
902         case ScreenRotation::ROTATION_180: {
903             Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
904                 absRect.top_ + containerConfig_.bp,
905                 absRect.GetRight() - containerConfig_.bp,
906                 absRect.GetBottom() - containerConfig_.bt};
907             Occlusion::Region r3{opaqueRect3};
908             opaqueRegion.OrSelf(r3);
909             break;
910         }
911         case ScreenRotation::ROTATION_270: {
912             Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
913                 absRect.top_ + containerConfig_.bp,
914                 absRect.GetRight() - containerConfig_.bt,
915                 absRect.GetBottom() - containerConfig_.bp};
916             Occlusion::Region r3{opaqueRect3};
917             opaqueRegion.OrSelf(r3);
918             break;
919         }
920         default: {
921             Occlusion::Rect opaqueRect3{ absRect.left_ + containerConfig_.bp,
922                 absRect.top_ + containerConfig_.bt,
923                 absRect.GetRight() - containerConfig_.bp,
924                 absRect.GetBottom() - containerConfig_.bp};
925             Occlusion::Region r3{opaqueRect3};
926             opaqueRegion.OrSelf(r3);
927             break;
928         }
929     }
930     return opaqueRegion;
931 }
932 
933 /*
934     If a surfacenode with containerwindow is a focused window, then its containerWindow region
935 should be set transparent, including: title, content padding area, border, and content corners.
936 Note this region is not centrosymmetric, hence it should be differentiated under different
937 screen rotation state as top/left/bottom/right has changed when screen rotated.
938 */
SetFocusedWindowOpaqueRegion(const RectI & absRect,const ScreenRotation screenRotation) const939 Occlusion::Region RSSurfaceRenderNode::SetFocusedWindowOpaqueRegion(const RectI& absRect,
940     const ScreenRotation screenRotation) const
941 {
942     Occlusion::Region opaqueRegion;
943     switch (screenRotation) {
944         case ScreenRotation::ROTATION_0: {
945             Occlusion::Rect opaqueRect1{
946                 absRect.left_ + containerConfig_.bp,
947                 absRect.top_ + containerConfig_.bt + containerConfig_.inR,
948                 absRect.GetRight() - containerConfig_.bp,
949                 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
950             Occlusion::Rect opaqueRect2{
951                 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
952                 absRect.top_ + containerConfig_.bt,
953                 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
954                 absRect.GetBottom() - containerConfig_.bp};
955             Occlusion::Region r1{opaqueRect1};
956             Occlusion::Region r2{opaqueRect2};
957             opaqueRegion = r1.Or(r2);
958             break;
959         }
960         case ScreenRotation::ROTATION_90: {
961             Occlusion::Rect opaqueRect1{
962                 absRect.left_ + containerConfig_.bt + containerConfig_.inR,
963                 absRect.top_ + containerConfig_.bp,
964                 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
965                 absRect.GetBottom() - containerConfig_.bp};
966             Occlusion::Rect opaqueRect2{
967                 absRect.left_ + containerConfig_.bt,
968                 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
969                 absRect.GetRight() - containerConfig_.bp,
970                 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
971             Occlusion::Region r1{opaqueRect1};
972             Occlusion::Region r2{opaqueRect2};
973             opaqueRegion = r1.Or(r2);
974             break;
975         }
976         case ScreenRotation::ROTATION_180: {
977             Occlusion::Rect opaqueRect1{
978                 absRect.left_ + containerConfig_.bp,
979                 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
980                 absRect.GetRight() - containerConfig_.bp,
981                 absRect.GetBottom() - containerConfig_.bt - containerConfig_.inR};
982             Occlusion::Rect opaqueRect2{
983                 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
984                 absRect.top_ + containerConfig_.bp,
985                 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
986                 absRect.GetBottom() - containerConfig_.bt};
987             Occlusion::Region r1{opaqueRect1};
988             Occlusion::Region r2{opaqueRect2};
989             opaqueRegion = r1.Or(r2);
990             break;
991         }
992         case ScreenRotation::ROTATION_270: {
993             Occlusion::Rect opaqueRect1{
994                 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
995                 absRect.top_ + containerConfig_.bp,
996                 absRect.GetRight() - containerConfig_.bt - containerConfig_.inR,
997                 absRect.GetBottom() - containerConfig_.bp};
998             Occlusion::Rect opaqueRect2{
999                 absRect.left_ + containerConfig_.bp,
1000                 absRect.top_ + containerConfig_.bp + containerConfig_.inR,
1001                 absRect.GetRight() - containerConfig_.bt,
1002                 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1003             Occlusion::Region r1{opaqueRect1};
1004             Occlusion::Region r2{opaqueRect2};
1005             opaqueRegion = r1.Or(r2);
1006             break;
1007         }
1008         default: {
1009             Occlusion::Rect opaqueRect1{
1010                 absRect.left_ + containerConfig_.bp,
1011                 absRect.top_ + containerConfig_.bt + containerConfig_.inR,
1012                 absRect.GetRight() - containerConfig_.bp,
1013                 absRect.GetBottom() - containerConfig_.bp - containerConfig_.inR};
1014             Occlusion::Rect opaqueRect2{
1015                 absRect.left_ + containerConfig_.bp + containerConfig_.inR,
1016                 absRect.top_ + containerConfig_.bt,
1017                 absRect.GetRight() - containerConfig_.bp - containerConfig_.inR,
1018                 absRect.GetBottom() - containerConfig_.bp};
1019             Occlusion::Region r1{opaqueRect1};
1020             Occlusion::Region r2{opaqueRect2};
1021             opaqueRegion = r1.Or(r2);
1022             break;
1023         }
1024     }
1025     return opaqueRegion;
1026 }
1027 
SetCornerRadiusOpaqueRegion(const RectI & absRect,float radius) const1028 Occlusion::Region RSSurfaceRenderNode::SetCornerRadiusOpaqueRegion(const RectI& absRect, float radius) const
1029 {
1030     Occlusion::Rect opaqueRect1{ absRect.left_ + radius,
1031         absRect.top_,
1032         absRect.GetRight() - radius,
1033         absRect.GetBottom()};
1034     Occlusion::Rect opaqueRect2{ absRect.left_,
1035         absRect.top_ + radius,
1036         absRect.GetRight(),
1037         absRect.GetBottom() - radius};
1038     Occlusion::Region r1{opaqueRect1};
1039     Occlusion::Region r2{opaqueRect2};
1040     Occlusion::Region opaqueRegion = r1.Or(r2);
1041     return opaqueRegion;
1042 }
1043 
ResetSurfaceContainerRegion(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation)1044 void RSSurfaceRenderNode::ResetSurfaceContainerRegion(const RectI& screeninfo, const RectI& absRect,
1045     const ScreenRotation screenRotation)
1046 {
1047     if (!HasContainerWindow()) {
1048         containerRegion_ = Occlusion::Region{};
1049         return;
1050     }
1051     Occlusion::Region absRegion{Occlusion::Rect{absRect}};
1052     Occlusion::Rect innerRect;
1053     switch (screenRotation) {
1054         case ScreenRotation::ROTATION_0: {
1055             innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1056                 absRect.top_ + containerConfig_.bt,
1057                 absRect.GetRight() - containerConfig_.bp,
1058                 absRect.GetBottom() - containerConfig_.bp};
1059             break;
1060         }
1061         case ScreenRotation::ROTATION_90: {
1062             innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bt,
1063                 absRect.top_ + containerConfig_.bp,
1064                 absRect.GetRight() - containerConfig_.bp,
1065                 absRect.GetBottom() - containerConfig_.bp};
1066             break;
1067         }
1068         case ScreenRotation::ROTATION_180: {
1069             innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1070                 absRect.top_ + containerConfig_.bp,
1071                 absRect.GetRight() - containerConfig_.bp,
1072                 absRect.GetBottom() - containerConfig_.bt};
1073             break;
1074         }
1075         case ScreenRotation::ROTATION_270: {
1076             innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1077                 absRect.top_ + containerConfig_.bp,
1078                 absRect.GetRight() - containerConfig_.bt,
1079                 absRect.GetBottom() - containerConfig_.bp};
1080             break;
1081         }
1082         default: {
1083             innerRect = Occlusion::Rect{ absRect.left_ + containerConfig_.bp,
1084                 absRect.top_ + containerConfig_.bt,
1085                 absRect.GetRight() - containerConfig_.bp,
1086                 absRect.GetBottom() - containerConfig_.bp};
1087             break;
1088         }
1089     }
1090     Occlusion::Region innerRectRegion{innerRect};
1091     containerRegion_ = absRegion.Sub(innerRectRegion);
1092 }
1093 
CheckOpaqueRegionBaseInfo(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow)1094 bool RSSurfaceRenderNode::CheckOpaqueRegionBaseInfo(
1095     const RectI& screeninfo, const RectI& absRect, const ScreenRotation screenRotation, const bool isFocusWindow)
1096 {
1097     return opaqueRegionBaseInfo_.screenRect_ == screeninfo &&
1098         opaqueRegionBaseInfo_.absRect_ == absRect &&
1099         opaqueRegionBaseInfo_.screenRotation_ == screenRotation &&
1100         opaqueRegionBaseInfo_.isFocusWindow_ == isFocusWindow &&
1101         opaqueRegionBaseInfo_.isTransparent_ == IsTransparent() &&
1102         opaqueRegionBaseInfo_.hasContainerWindow_ == HasContainerWindow();
1103 }
1104 
SetOpaqueRegionBaseInfo(const RectI & screeninfo,const RectI & absRect,const ScreenRotation screenRotation,const bool isFocusWindow)1105 void RSSurfaceRenderNode::SetOpaqueRegionBaseInfo(
1106     const RectI& screeninfo, const RectI& absRect, const ScreenRotation screenRotation, const bool isFocusWindow)
1107 {
1108     opaqueRegionBaseInfo_.screenRect_ = screeninfo;
1109     opaqueRegionBaseInfo_.absRect_ = absRect;
1110     opaqueRegionBaseInfo_.screenRotation_ = screenRotation;
1111     opaqueRegionBaseInfo_.isFocusWindow_ = isFocusWindow;
1112     opaqueRegionBaseInfo_.isTransparent_ = IsTransparent();
1113     opaqueRegionBaseInfo_.hasContainerWindow_ = HasContainerWindow();
1114 }
1115 
1116 // [planning] Remove this after skia is upgraded, the clipRegion is supported
ResetChildrenFilterRects()1117 void RSSurfaceRenderNode::ResetChildrenFilterRects()
1118 {
1119     childrenFilterRects_.clear();
1120 }
1121 
UpdateChildrenFilterRects(const RectI & rect)1122 void RSSurfaceRenderNode::UpdateChildrenFilterRects(const RectI& rect)
1123 {
1124     if (!rect.IsEmpty()) {
1125         childrenFilterRects_.emplace_back(rect);
1126     }
1127 }
1128 
GetChildrenNeedFilterRects() const1129 const std::vector<RectI>& RSSurfaceRenderNode::GetChildrenNeedFilterRects() const
1130 {
1131     return childrenFilterRects_;
1132 }
1133 
1134 // manage abilities' nodeid info
ResetAbilityNodeIds()1135 void RSSurfaceRenderNode::ResetAbilityNodeIds()
1136 {
1137     abilityNodeIds_.clear();
1138 }
1139 
UpdateAbilityNodeIds(NodeId id)1140 void RSSurfaceRenderNode::UpdateAbilityNodeIds(NodeId id)
1141 {
1142     abilityNodeIds_.emplace_back(id);
1143 }
1144 
GetAbilityNodeIds() const1145 const std::vector<NodeId>& RSSurfaceRenderNode::GetAbilityNodeIds() const
1146 {
1147     return abilityNodeIds_;
1148 }
1149 
ResetChildHardwareEnabledNodes()1150 void RSSurfaceRenderNode::ResetChildHardwareEnabledNodes()
1151 {
1152     childHardwareEnabledNodes_.clear();
1153 }
1154 
AddChildHardwareEnabledNode(std::weak_ptr<RSSurfaceRenderNode> childNode)1155 void RSSurfaceRenderNode::AddChildHardwareEnabledNode(std::weak_ptr<RSSurfaceRenderNode> childNode)
1156 {
1157     childHardwareEnabledNodes_.emplace_back(childNode);
1158 }
1159 
GetChildHardwareEnabledNodes() const1160 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& RSSurfaceRenderNode::GetChildHardwareEnabledNodes() const
1161 {
1162     return childHardwareEnabledNodes_;
1163 }
1164 
SetLocalZOrder(float localZOrder)1165 void RSSurfaceRenderNode::SetLocalZOrder(float localZOrder)
1166 {
1167     localZOrder_ = localZOrder;
1168 }
1169 
GetLocalZOrder() const1170 float RSSurfaceRenderNode::GetLocalZOrder() const
1171 {
1172     return localZOrder_;
1173 }
1174 
OnApplyModifiers()1175 void RSSurfaceRenderNode::OnApplyModifiers()
1176 {
1177     auto& properties = GetMutableRenderProperties();
1178     auto geoPtr = (properties.GetBoundsGeometry());
1179 
1180     // Multiply context alpha into alpha
1181     properties.SetAlpha(properties.GetAlpha() * contextAlpha_);
1182 
1183     // Apply the context matrix into the bounds geometry
1184     geoPtr->SetContextMatrix(contextMatrix_);
1185 }
1186 
1187 #ifndef USE_ROSEN_DRAWING
GetContextClipRegion() const1188 std::optional<SkRect> RSSurfaceRenderNode::GetContextClipRegion() const
1189 {
1190     return contextClipRect_;
1191 }
1192 #else
GetContextClipRegion() const1193 std::optional<Drawing::Rect> RSSurfaceRenderNode::GetContextClipRegion() const
1194 {
1195     return contextClipRect_;
1196 }
1197 #endif
1198 
LeashWindowRelatedAppWindowOccluded(std::shared_ptr<RSSurfaceRenderNode> & appNode)1199 bool RSSurfaceRenderNode::LeashWindowRelatedAppWindowOccluded(std::shared_ptr<RSSurfaceRenderNode>& appNode)
1200 {
1201     if (!IsLeashWindow()) {
1202         return false;
1203     }
1204     for (auto& childNode : GetChildren()) {
1205         const auto& childNodeSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(childNode);
1206         if (childNodeSurface && childNodeSurface->GetVisibleRegion().IsEmpty()) {
1207             appNode = childNodeSurface;
1208             return true;
1209         }
1210     }
1211     return false;
1212 }
1213 
GetLeashWindowNestedSurfaces()1214 std::vector<std::shared_ptr<RSSurfaceRenderNode>> RSSurfaceRenderNode::GetLeashWindowNestedSurfaces()
1215 {
1216     std::vector<std::shared_ptr<RSSurfaceRenderNode>> res;
1217     if (!IsLeashWindow()) {
1218         return res;
1219     }
1220     for (auto& childNode : GetChildren()) {
1221         if (childNode) {
1222             auto childNodeSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(childNode);
1223             if (childNodeSurface) {
1224                 res.emplace_back(childNodeSurface);
1225             }
1226         }
1227     }
1228     return res;
1229 }
1230 
IsCurrentFrameStatic()1231 bool RSSurfaceRenderNode::IsCurrentFrameStatic()
1232 {
1233     if (dirtyManager_ == nullptr || !dirtyManager_->GetCurrentFrameDirtyRegion().IsEmpty()) {
1234         return false;
1235     }
1236     if (IsAppWindow()) {
1237         auto hardwareEnabledNodes = GetChildHardwareEnabledNodes();
1238         for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
1239             auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
1240             if (hardwareEnabledNodePtr && hardwareEnabledNodePtr->IsCurrentFrameBufferConsumed()) {
1241                 return false;
1242             }
1243         }
1244     }
1245     if (IsMainWindowType()) {
1246         return true;
1247     } else if (IsLeashWindow()) {
1248         // leashwindow subthread cache considered static if and only if all nested surfacenode static
1249         // (include appwindow and starting window)
1250         auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1251         for (auto& nestedSurface: nestedSurfaceNodes) {
1252             if (nestedSurface && !nestedSurface->IsCurrentFrameStatic()) {
1253                 return false;
1254             }
1255         }
1256         return true;
1257     } else if (IsSelfDrawingType()) {
1258         return isCurrentFrameBufferConsumed_;
1259     } else {
1260         return false;
1261     }
1262 }
1263 
UpdateCacheSurfaceDirtyManager(int bufferAge)1264 void RSSurfaceRenderNode::UpdateCacheSurfaceDirtyManager(int bufferAge)
1265 {
1266     if (!cacheSurfaceDirtyManager_ || !dirtyManager_) {
1267         return;
1268     }
1269     cacheSurfaceDirtyManager_->Clear();
1270     cacheSurfaceDirtyManager_->MergeDirtyRect(dirtyManager_->GetLatestDirtyRegion());
1271     cacheSurfaceDirtyManager_->SetBufferAge(bufferAge);
1272     cacheSurfaceDirtyManager_->UpdateDirty(false);
1273     // for leashwindow type, nested app surfacenode's cacheSurfaceDirtyManager update is required
1274     auto nestedSurfaceNodes = GetLeashWindowNestedSurfaces();
1275     for (auto& nestedSurface : nestedSurfaceNodes) {
1276         if (nestedSurface) {
1277             nestedSurface->UpdateCacheSurfaceDirtyManager(bufferAge);
1278         }
1279     }
1280 }
1281 
1282 #ifdef OHOS_PLATFORM
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId)1283 void RSSurfaceRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId)
1284 {
1285     instanceRootNodeId = (IsMainWindowType() || IsLeashWindow()) ? GetId() : instanceRootNodeId;
1286     RSBaseRenderNode::SetIsOnTheTree(flag, instanceRootNodeId);
1287     if (flag == isReportFirstFrame_ || !IsAppWindow()) {
1288         return;
1289     }
1290     if (flag) {
1291         RSJankStats::GetInstance().SetFirstFrame();
1292         RSJankStats::GetInstance().SetPid(ExtractPid(GetId()));
1293     }
1294     isReportFirstFrame_ = flag;
1295 }
1296 #endif
1297 
GetCacheSurfaceProcessedStatus() const1298 CacheProcessStatus RSSurfaceRenderNode::GetCacheSurfaceProcessedStatus() const
1299 {
1300     return cacheProcessStatus_.load();
1301 }
1302 
SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)1303 void RSSurfaceRenderNode::SetCacheSurfaceProcessedStatus(CacheProcessStatus cacheProcessStatus)
1304 {
1305     cacheProcessStatus_.store(cacheProcessStatus);
1306 }
1307 
NodeIsUsedBySubThread() const1308 bool RSSurfaceRenderNode::NodeIsUsedBySubThread() const
1309 {
1310     return GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING;
1311 }
1312 } // namespace Rosen
1313 } // namespace OHOS
1314