• 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 #include "include/core/SkMatrix.h"
19 #include "include/core/SkRect.h"
20 #include "include/gpu/GrContext.h"
21 
22 #include "command/rs_surface_node_command.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "common/rs_rect.h"
25 #include "common/rs_vector2.h"
26 #include "common/rs_vector4.h"
27 #include "pipeline/rs_render_node.h"
28 #include "pipeline/rs_root_render_node.h"
29 #include "platform/common/rs_log.h"
30 #include "property/rs_properties_painter.h"
31 #include "transaction/rs_render_service_client.h"
32 #include "visitor/rs_node_visitor.h"
33 
34 namespace OHOS {
35 namespace Rosen {
RSSurfaceRenderNode(const RSSurfaceRenderNodeConfig & config,std::weak_ptr<RSContext> context)36 RSSurfaceRenderNode::RSSurfaceRenderNode(const RSSurfaceRenderNodeConfig& config, std::weak_ptr<RSContext> context)
37     : RSRenderNode(config.id, context),
38       RSSurfaceHandler(config.id),
39       name_(config.name),
40       nodeType_(config.nodeType),
41       dirtyManager_(std::make_shared<RSDirtyRegionManager>())
42 {}
43 
RSSurfaceRenderNode(NodeId id,std::weak_ptr<RSContext> context)44 RSSurfaceRenderNode::RSSurfaceRenderNode(NodeId id, std::weak_ptr<RSContext> context)
45     : RSSurfaceRenderNode(RSSurfaceRenderNodeConfig{id, "SurfaceNode"}, context)
46 {}
47 
~RSSurfaceRenderNode()48 RSSurfaceRenderNode::~RSSurfaceRenderNode() {}
49 
50 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
SetConsumer(const sptr<Surface> & consumer)51 void RSSurfaceRenderNode::SetConsumer(const sptr<Surface>& consumer)
52 {
53     consumer_ = consumer;
54 }
55 #endif
56 
getLocalClipBounds(const RSPaintFilterCanvas & canvas)57 static SkRect getLocalClipBounds(const RSPaintFilterCanvas& canvas)
58 {
59     SkIRect ibounds = canvas.getDeviceClipBounds();
60     if (ibounds.isEmpty()) {
61         return SkRect::MakeEmpty();
62     }
63 
64     SkMatrix inverse;
65     // if we can't invert the CTM, we can't return local clip bounds
66     if (!(canvas.getTotalMatrix().invert(&inverse))) {
67         return SkRect::MakeEmpty();
68     }
69     SkRect bounds;
70     SkRect r = SkRect::Make(ibounds);
71     inverse.mapRect(&bounds, r);
72     return bounds;
73 }
74 
PrepareRenderBeforeChildren(RSPaintFilterCanvas & canvas)75 void RSSurfaceRenderNode::PrepareRenderBeforeChildren(RSPaintFilterCanvas& canvas)
76 {
77     renderNodeSaveCount_ = canvas.SaveCanvasAndAlpha();
78 
79     // apply intermediate properties from RT to canvas
80     canvas.MultiplyAlpha(GetContextAlpha());
81     canvas.concat(GetContextMatrix());
82     auto clipRectFromRT = GetContextClipRegion();
83     if (clipRectFromRT.width() > std::numeric_limits<float>::epsilon() &&
84         clipRectFromRT.height() > std::numeric_limits<float>::epsilon()) {
85         canvas.clipRect(clipRectFromRT);
86     }
87 
88     // apply node properties to canvas
89     const RSProperties& properties = GetRenderProperties();
90     canvas.MultiplyAlpha(properties.GetAlpha());
91     auto currentGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(properties.GetBoundsGeometry());
92     if (currentGeoPtr != nullptr) {
93         currentGeoPtr->UpdateByMatrixFromSelf();
94         auto matrix = currentGeoPtr->GetMatrix();
95         matrix.setTranslateX(std::ceil(matrix.getTranslateX()));
96         matrix.setTranslateY(std::ceil(matrix.getTranslateY()));
97         canvas.concat(matrix);
98     }
99 
100     // clip by bounds
101     canvas.clipRect(
102         SkRect::MakeWH(std::floor(properties.GetBoundsWidth()), std::floor(properties.GetBoundsHeight())));
103 
104     // extract srcDest and dstRect from SkCanvas, localCLipBounds as SrcRect, deviceClipBounds as DstRect
105     auto localClipRect = getLocalClipBounds(canvas);
106     RectI srcRect = {
107         std::clamp<int>(localClipRect.left(), 0, properties.GetBoundsWidth()),
108         std::clamp<int>(localClipRect.top(), 0, properties.GetBoundsHeight()),
109         std::clamp<int>(localClipRect.width(), 0, properties.GetBoundsWidth() - localClipRect.left()),
110         std::clamp<int>(localClipRect.height(), 0, properties.GetBoundsHeight() - localClipRect.top())
111     };
112     SetSrcRect(srcRect);
113     auto deviceClipRect = canvas.getDeviceClipBounds();
114     RectI dstRect = { deviceClipRect.left(), deviceClipRect.top(), deviceClipRect.width(), deviceClipRect.height() };
115     SetDstRect(dstRect);
116 
117     // save TotalMatrix and GlobalAlpha for compositor
118     SetTotalMatrix(canvas.getTotalMatrix());
119     SetGlobalAlpha(canvas.GetAlpha());
120 }
121 
PrepareRenderAfterChildren(RSPaintFilterCanvas & canvas)122 void RSSurfaceRenderNode::PrepareRenderAfterChildren(RSPaintFilterCanvas& canvas)
123 {
124     canvas.RestoreCanvasAndAlpha(renderNodeSaveCount_);
125 }
126 
CollectSurface(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<RSBaseRenderNode::SharedPtr> & vec,bool isUniRender)127 void RSSurfaceRenderNode::CollectSurface(
128     const std::shared_ptr<RSBaseRenderNode>& node, std::vector<RSBaseRenderNode::SharedPtr>& vec, bool isUniRender)
129 {
130     if (nodeType_ == RSSurfaceNodeType::STARTING_WINDOW_NODE) {
131         if (isUniRender) {
132             vec.emplace_back(shared_from_this());
133         }
134         return;
135     }
136     if (nodeType_ == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
137         for (auto& child : node->GetSortedChildren()) {
138             child->CollectSurface(child, vec, isUniRender);
139         }
140         return;
141     }
142 
143 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
144     auto& consumer = GetConsumer();
145     if (consumer != nullptr && consumer->GetTunnelHandle() != nullptr) {
146         return;
147     }
148 #endif
149     auto num = find(vec.begin(), vec.end(), shared_from_this());
150     if (num != vec.end()) {
151         return;
152     }
153     if (isUniRender && ShouldPaint()) {
154         vec.emplace_back(shared_from_this());
155     } else {
156 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
157         if (GetBuffer() != nullptr && ShouldPaint()) {
158             vec.emplace_back(shared_from_this());
159         }
160 #endif
161     }
162 }
163 
ClearChildrenCache(const std::shared_ptr<RSBaseRenderNode> & node)164 void RSSurfaceRenderNode::ClearChildrenCache(const std::shared_ptr<RSBaseRenderNode>& node)
165 {
166     for (auto& child : node->GetSortedChildren()) {
167         auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>();
168         if (surfaceNode == nullptr) {
169             continue;
170         }
171 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
172         auto& consumer = surfaceNode->GetConsumer();
173         if (consumer != nullptr) {
174             consumer->GoBackground();
175         }
176 #endif
177     }
178 }
179 
ResetParent()180 void RSSurfaceRenderNode::ResetParent()
181 {
182     RSBaseRenderNode::ResetParent();
183 
184     if (nodeType_ == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
185         ClearChildrenCache(shared_from_this());
186     } else {
187 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
188         auto& consumer = GetConsumer();
189         if (consumer != nullptr &&
190             (GetSurfaceNodeType() != RSSurfaceNodeType::SELF_DRAWING_NODE &&
191             GetSurfaceNodeType() != RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE &&
192             GetSurfaceNodeType() != RSSurfaceNodeType::ABILITY_COMPONENT_NODE)) {
193             consumer->GoBackground();
194         }
195 #endif
196     }
197 }
198 
SetIsNotifyUIBufferAvailable(bool available)199 void RSSurfaceRenderNode::SetIsNotifyUIBufferAvailable(bool available)
200 {
201     isNotifyUIBufferAvailable_.store(available);
202 }
203 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)204 void RSSurfaceRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
205 {
206     if (!visitor) {
207         return;
208     }
209     visitor->PrepareSurfaceRenderNode(*this);
210 }
211 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)212 void RSSurfaceRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
213 {
214     if (!visitor) {
215         return;
216     }
217     RSRenderNode::RenderTraceDebug();
218     visitor->ProcessSurfaceRenderNode(*this);
219 }
220 
SetContextBounds(const Vector4f bounds)221 void RSSurfaceRenderNode::SetContextBounds(const Vector4f bounds)
222 {
223     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetBounds>(GetId(), bounds);
224     SendCommandFromRT(command, GetId());
225 }
226 
GetDirtyManager() const227 std::shared_ptr<RSDirtyRegionManager> RSSurfaceRenderNode::GetDirtyManager() const
228 {
229     return dirtyManager_;
230 }
231 
SetContextMatrix(const SkMatrix & matrix,bool sendMsg)232 void RSSurfaceRenderNode::SetContextMatrix(const SkMatrix& matrix, bool sendMsg)
233 {
234     if (contextMatrix_ == matrix) {
235         return;
236     }
237     contextMatrix_ = matrix;
238     SetDirty();
239     if (!sendMsg) {
240         return;
241     }
242     // send a Command
243     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextMatrix>(GetId(), matrix);
244     SendCommandFromRT(command, GetId());
245 }
246 
GetContextMatrix() const247 const SkMatrix& RSSurfaceRenderNode::GetContextMatrix() const
248 {
249     return contextMatrix_;
250 }
251 
SetContextAlpha(float alpha,bool sendMsg)252 void RSSurfaceRenderNode::SetContextAlpha(float alpha, bool sendMsg)
253 {
254     if (contextAlpha_ == alpha) {
255         return;
256     }
257     contextAlpha_ = alpha;
258     SetDirty();
259     if (!sendMsg) {
260         return;
261     }
262     // send a Command
263     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextAlpha>(GetId(), alpha);
264     SendCommandFromRT(command, GetId());
265 }
266 
GetContextAlpha() const267 float RSSurfaceRenderNode::GetContextAlpha() const
268 {
269     return contextAlpha_;
270 }
271 
SetContextClipRegion(SkRect clipRegion,bool sendMsg)272 void RSSurfaceRenderNode::SetContextClipRegion(SkRect clipRegion, bool sendMsg)
273 {
274     if (contextClipRect_ == clipRegion) {
275         return;
276     }
277     contextClipRect_ = clipRegion;
278     SetDirty();
279     if (!sendMsg) {
280         return;
281     }
282     // send a Command
283     std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeSetContextClipRegion>(GetId(), clipRegion);
284     SendCommandFromRT(command, GetId());
285 }
286 
GetContextClipRegion() const287 const SkRect& RSSurfaceRenderNode::GetContextClipRegion() const
288 {
289     return contextClipRect_;
290 }
291 
SetSecurityLayer(bool isSecurityLayer)292 void RSSurfaceRenderNode::SetSecurityLayer(bool isSecurityLayer)
293 {
294     isSecurityLayer_ = isSecurityLayer;
295 }
296 
GetSecurityLayer() const297 bool RSSurfaceRenderNode::GetSecurityLayer() const
298 {
299     return isSecurityLayer_;
300 }
301 
302 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
SetColorSpace(ColorGamut colorSpace)303 void RSSurfaceRenderNode::SetColorSpace(ColorGamut colorSpace)
304 {
305     colorSpace_ = colorSpace;
306 }
307 
GetColorSpace() const308 ColorGamut RSSurfaceRenderNode::GetColorSpace() const
309 {
310     return colorSpace_;
311 }
312 #endif
313 
UpdateSurfaceDefaultSize(float width,float height)314 void RSSurfaceRenderNode::UpdateSurfaceDefaultSize(float width, float height)
315 {
316 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
317     if (consumer_ != nullptr) {
318         consumer_->SetDefaultWidthAndHeight(width, height);
319     }
320 #endif
321 }
322 
323 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__gnu_linux__)
GetBlendType()324 GraphicBlendType RSSurfaceRenderNode::GetBlendType()
325 {
326     return blendType_;
327 }
328 
SetBlendType(GraphicBlendType blendType)329 void RSSurfaceRenderNode::SetBlendType(GraphicBlendType blendType)
330 {
331     blendType_ = blendType;
332 }
333 #endif
334 
RegisterBufferAvailableListener(sptr<RSIBufferAvailableCallback> callback,bool isFromRenderThread)335 void RSSurfaceRenderNode::RegisterBufferAvailableListener(
336     sptr<RSIBufferAvailableCallback> callback, bool isFromRenderThread)
337 {
338     if (isFromRenderThread) {
339         std::lock_guard<std::mutex> lock(mutexRT_);
340         callbackFromRT_ = callback;
341     } else {
342         std::lock_guard<std::mutex> lock(mutexUI_);
343         callbackFromUI_ = callback;
344     }
345 }
346 
ConnectToNodeInRenderService()347 void RSSurfaceRenderNode::ConnectToNodeInRenderService()
348 {
349     ROSEN_LOGI("RSSurfaceRenderNode::ConnectToNodeInRenderService nodeId = %" PRIu64, GetId());
350     auto renderServiceClient =
351         std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
352     if (renderServiceClient != nullptr) {
353         renderServiceClient->RegisterBufferAvailableListener(
354             GetId(), [weakThis = weak_from_this()]() {
355                 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(weakThis.lock());
356                 if (node == nullptr) {
357                     return;
358                 }
359                 node->NotifyRTBufferAvailable();
360             }, true);
361     }
362 }
363 
NotifyRTBufferAvailable()364 void RSSurfaceRenderNode::NotifyRTBufferAvailable()
365 {
366     // In RS, "isNotifyRTBufferAvailable_ = true" means buffer is ready and need to trigger ipc callback.
367     // In RT, "isNotifyRTBufferAvailable_ = true" means RT know that RS have had available buffer
368     // and ready to trigger "callbackForRenderThreadRefresh_" to "clip" on parent surface.
369     isNotifyRTBufferAvailablePre_ = isNotifyRTBufferAvailable_;
370     if (isNotifyRTBufferAvailable_) {
371         return;
372     }
373     isNotifyRTBufferAvailable_ = true;
374 
375     if (callbackForRenderThreadRefresh_) {
376         ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %" PRIu64 " RenderThread", GetId());
377         callbackForRenderThreadRefresh_();
378     }
379 
380     {
381         std::lock_guard<std::mutex> lock(mutexRT_);
382         if (callbackFromRT_) {
383             ROSEN_LOGI("RSSurfaceRenderNode::NotifyRTBufferAvailable nodeId = %" PRIu64 " RenderService", GetId());
384             callbackFromRT_->OnBufferAvailable();
385         }
386         if (!callbackForRenderThreadRefresh_ && !callbackFromRT_) {
387             isNotifyRTBufferAvailable_ = false;
388         }
389     }
390 }
391 
NotifyUIBufferAvailable()392 void RSSurfaceRenderNode::NotifyUIBufferAvailable()
393 {
394     if (isNotifyUIBufferAvailable_) {
395         return;
396     }
397     isNotifyUIBufferAvailable_ = true;
398     {
399         std::lock_guard<std::mutex> lock(mutexUI_);
400         if (callbackFromUI_) {
401             ROSEN_LOGD("RSSurfaceRenderNode::NotifyUIBufferAvailable nodeId = %" PRIu64, GetId());
402             callbackFromUI_->OnBufferAvailable();
403         } else {
404             isNotifyUIBufferAvailable_ = false;
405         }
406     }
407 }
408 
IsNotifyRTBufferAvailable() const409 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailable() const
410 {
411     return isNotifyRTBufferAvailable_;
412 }
413 
IsNotifyRTBufferAvailablePre() const414 bool RSSurfaceRenderNode::IsNotifyRTBufferAvailablePre() const
415 {
416     return isNotifyRTBufferAvailablePre_;
417 }
418 
IsNotifyUIBufferAvailable() const419 bool RSSurfaceRenderNode::IsNotifyUIBufferAvailable() const
420 {
421     return isNotifyUIBufferAvailable_;
422 }
423 
SetCallbackForRenderThreadRefresh(std::function<void (void)> callback)424 void RSSurfaceRenderNode::SetCallbackForRenderThreadRefresh(std::function<void(void)> callback)
425 {
426     callbackForRenderThreadRefresh_ = callback;
427 }
428 
NeedSetCallbackForRenderThreadRefresh()429 bool RSSurfaceRenderNode::NeedSetCallbackForRenderThreadRefresh()
430 {
431     return (callbackForRenderThreadRefresh_ == nullptr);
432 }
433 
IsStartAnimationFinished() const434 bool RSSurfaceRenderNode::IsStartAnimationFinished() const
435 {
436     return startAnimationFinished_;
437 }
438 
SetStartAnimationFinished()439 void RSSurfaceRenderNode::SetStartAnimationFinished()
440 {
441     RS_LOGD("RSSurfaceRenderNode::SetStartAnimationFinished");
442     startAnimationFinished_ = true;
443 }
444 
SetVisibleRegionRecursive(const Occlusion::Region & region,VisibleData & visibleVec,std::map<uint32_t,bool> & pidVisMap)445 void RSSurfaceRenderNode::SetVisibleRegionRecursive(const Occlusion::Region& region,
446                                                     VisibleData& visibleVec,
447                                                     std::map<uint32_t, bool>& pidVisMap)
448 {
449     if (nodeType_ == RSSurfaceNodeType::SELF_DRAWING_NODE ||
450         nodeType_ == RSSurfaceNodeType::ABILITY_COMPONENT_NODE) {
451         SetOcclusionVisible(true);
452         return;
453     }
454     visibleRegion_ = region;
455     bool vis = region.GetSize() > 0;
456     if (vis) {
457         visibleVec.emplace_back(GetId());
458     }
459 
460     // collect visible changed pid
461     if (qosPidCal_ && GetType() == RSRenderNodeType::SURFACE_NODE) {
462         uint32_t tmpPid = (GetId() >> 32) & 0xFFFFFFFF;
463         if (pidVisMap.find(tmpPid) != pidVisMap.end()) {
464             pidVisMap[tmpPid] |= vis;
465         } else {
466             pidVisMap[tmpPid] = vis;
467         }
468     }
469 
470     SetOcclusionVisible(vis);
471     for (auto& child : GetSortedChildren()) {
472         if (auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)) {
473             surface->SetVisibleRegionRecursive(region, visibleVec, pidVisMap);
474         }
475     }
476 }
477 } // namespace Rosen
478 } // namespace OHOS
479