• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_render_node_allocator.h"
17 
18 #include "common/rs_optional_trace.h"
19 #include "pipeline/rs_render_node_gc.h"
20 #include "platform/common/rs_log.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25 constexpr uint32_t NODE_ALLOCATOR_LIMIT = 512;
26 constexpr uint32_t DRAWABLE_ALLOCATOR_LIMIT = 512;
27 }
28 
Instance()29 RSRenderNodeAllocator& RSRenderNodeAllocator::Instance()
30 {
31     static RSRenderNodeAllocator instance;
32     return instance;
33 }
34 
AddNodeToAllocator(RSRenderNode * ptr)35 bool RSRenderNodeAllocator::AddNodeToAllocator(RSRenderNode* ptr)
36 {
37     if (ptr == nullptr || ptr->GetType() != RSRenderNodeType::CANVAS_NODE) {
38         return false;
39     }
40 
41     nodeAllocatorSpinlock_.lock();
42     if (nodeAllocator_.size() >= NODE_ALLOCATOR_LIMIT) {
43         nodeAllocatorSpinlock_.unlock();
44         RS_OPTIONAL_TRACE_NAME("AddNodeToAllocator nodeAllocator is full.");
45         return false;
46     }
47     ptr->~RSRenderNode();
48     nodeAllocator_.push(ptr);
49     RS_LOGD("AddNodeToAllocator, pool size:%{public}zu", nodeAllocator_.size());
50     nodeAllocatorSpinlock_.unlock();
51     return true;
52 }
53 
AddDrawableToAllocator(RSRenderNodeAllocator::DrawablePtr ptr)54 bool RSRenderNodeAllocator::AddDrawableToAllocator(RSRenderNodeAllocator::DrawablePtr ptr)
55 {
56     if (ptr == nullptr || ptr->GetNodeType() != RSRenderNodeType::CANVAS_NODE) {
57         return false;
58     }
59 
60     if (ptr->GetDrawableType() != RSRenderNodeDrawableType::CANVAS_NODE_DRAWABLE) {
61         RS_LOGI("AddDrawableToAllocator, not canvas node drawable.");
62         return false;
63     }
64     drawableAllocatorSpinlock_.lock();
65     if (drawableAllocator_.size() >= DRAWABLE_ALLOCATOR_LIMIT) {
66         drawableAllocatorSpinlock_.unlock();
67         RS_OPTIONAL_TRACE_NAME("AddDrawableToAllocator drawableAllocator is full.");
68         return false;
69     }
70     ptr->~RSRenderNodeDrawableAdapter();
71     drawableAllocator_.push(ptr);
72     RS_LOGD("AddDrawableToAllocator, pool size:%{public}zu", drawableAllocator_.size());
73     drawableAllocatorSpinlock_.unlock();
74     return true;
75 }
76 
CreateRSCanvasRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)77 std::shared_ptr<RSCanvasRenderNode> RSRenderNodeAllocator::CreateRSCanvasRenderNode(NodeId id,
78     const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
79 {
80     nodeAllocatorSpinlock_.lock();
81     if (nodeAllocator_.empty()) {
82         nodeAllocatorSpinlock_.unlock();
83         RS_OPTIONAL_TRACE_NAME("CreateRSCanvasRenderNode nodeAllocator is empty.");
84         return std::shared_ptr<RSCanvasRenderNode>(new RSCanvasRenderNode(id,
85             context, isTextureExportNode), RSRenderNodeGC::NodeDestructor);
86     }
87     auto front = nodeAllocator_.front();
88     nodeAllocator_.pop();
89     nodeAllocatorSpinlock_.unlock();
90     RS_LOGD("CreateRSCanvasRenderNode in pool, pool size:%{public}zu, id:%{public}" PRIu64 "",
91         nodeAllocator_.size(), id);
92     return std::shared_ptr<RSCanvasRenderNode>(new (front)RSCanvasRenderNode(id,
93         context, isTextureExportNode), RSRenderNodeGC::NodeDestructor);
94 }
95 
CreateRSRenderNodeDrawable(std::shared_ptr<const RSRenderNode> node,std::function<RSRenderNodeAllocator::DrawablePtr (std::shared_ptr<const RSRenderNode> node,RSRenderNodeAllocator::DrawablePtr front)> generator)96 RSRenderNodeAllocator::DrawablePtr RSRenderNodeAllocator::CreateRSRenderNodeDrawable(
97     std::shared_ptr<const RSRenderNode> node,
98     std::function<RSRenderNodeAllocator::DrawablePtr(std::shared_ptr<const RSRenderNode> node,
99         RSRenderNodeAllocator::DrawablePtr front)> generator)
100 {
101     drawableAllocatorSpinlock_.lock();
102     if (drawableAllocator_.empty()) {
103         drawableAllocatorSpinlock_.unlock();
104         RS_OPTIONAL_TRACE_NAME("CreateRSRenderNodeDrawable drawableAllocator is empty.");
105         return generator(node, nullptr);
106     }
107     auto front = drawableAllocator_.front();
108     drawableAllocator_.pop();
109     RS_LOGD("CreateRSRenderNodeDrawable in pool, pool size:%{public}zu", nodeAllocator_.size());
110     drawableAllocatorSpinlock_.unlock();
111     return generator(node, front);
112 }
113 
114 } // namespace Rosen
115 } // namespace OHOS