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