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