• 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 "ui/rs_canvas_node.h"
17 
18 #include <algorithm>
19 #include <string>
20 
21 #include "common/rs_obj_abs_geometry.h"
22 #include "command/rs_canvas_node_command.h"
23 #include "command/rs_node_command.h"
24 #include "platform/common/rs_log.h"
25 #include "common/rs_obj_geometry.h"
26 #include "pipeline/rs_draw_cmd_list.h"
27 #include "pipeline/rs_node_map.h"
28 #include "transaction/rs_transaction_proxy.h"
29 
30 namespace OHOS {
31 namespace Rosen {
Create(bool isRenderServiceNode,bool isTextureExportNode)32 RSCanvasNode::SharedPtr RSCanvasNode::Create(bool isRenderServiceNode, bool isTextureExportNode)
33 {
34     SharedPtr node(new RSCanvasNode(isRenderServiceNode, isTextureExportNode));
35     RSNodeMap::MutableInstance().RegisterNode(node);
36 
37     auto transactionProxy = RSTransactionProxy::GetInstance();
38     if (transactionProxy == nullptr) {
39         return node;
40     }
41     std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasNodeCreate>(node->GetId(), isTextureExportNode);
42     transactionProxy->AddCommand(command, node->IsRenderServiceNode());
43     return node;
44 }
45 
RSCanvasNode(bool isRenderServiceNode,bool isTextureExportNode)46 RSCanvasNode::RSCanvasNode(bool isRenderServiceNode, bool isTextureExportNode)
47     : RSNode(isRenderServiceNode, isTextureExportNode) {}
48 
~RSCanvasNode()49 RSCanvasNode::~RSCanvasNode() {}
50 
51 #ifndef USE_ROSEN_DRAWING
BeginRecording(int width,int height)52 SkCanvas* RSCanvasNode::BeginRecording(int width, int height)
53 {
54     recordingCanvas_ = new RSRecordingCanvas(width, height);
55     static_cast<RSRecordingCanvas*>(recordingCanvas_)->SetIsCustomTextType(isCustomTextType_);
56 #else
57 ExtendRecordingCanvas* RSCanvasNode::BeginRecording(int width, int height)
58 {
59     recordingCanvas_ = new ExtendRecordingCanvas(width, height);
60     recordingCanvas_->SetIsCustomTextType(isCustomTextType_);
61 #endif
62     auto transactionProxy = RSTransactionProxy::GetInstance();
63     if (transactionProxy == nullptr) {
64         return recordingCanvas_;
65     }
66     if (!recordingUpdated_) {
67         return recordingCanvas_;
68     }
69     recordingUpdated_ = false;
70     std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasNodeClearRecording>(GetId());
71     transactionProxy->AddCommand(command, IsRenderServiceNode());
72     return recordingCanvas_;
73 }
74 
75 bool RSCanvasNode::IsRecording() const
76 {
77     return recordingCanvas_ != nullptr;
78 }
79 
80 void RSCanvasNode::FinishRecording()
81 {
82     if (!IsRecording()) {
83         return;
84     }
85 #ifndef USE_ROSEN_DRAWING
86     auto recording = static_cast<RSRecordingCanvas*>(recordingCanvas_)->GetDrawCmdList();
87 #else
88     auto recording = recordingCanvas_->GetDrawCmdList();
89 #endif
90     delete recordingCanvas_;
91     recordingCanvas_ = nullptr;
92 #ifndef USE_ROSEN_DRAWING
93     if (recording && recording->GetSize() == 0) {
94 #else
95     if (recording && recording->IsEmpty()) {
96 #endif
97         return;
98     }
99     if (recording != nullptr && RSSystemProperties::GetDrawTextAsBitmap()) {
100         // replace drawOpItem with cached one (generated by CPU)
101         recording->GenerateCache();
102     }
103     auto transactionProxy = RSTransactionProxy::GetInstance();
104     if (transactionProxy == nullptr) {
105         return;
106     }
107     std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording,
108         drawContentLast_ ? static_cast<uint16_t>(RSModifierType::FOREGROUND_STYLE)
109                          : static_cast<uint16_t>(RSModifierType::CONTENT_STYLE));
110     transactionProxy->AddCommand(command, IsRenderServiceNode());
111     recordingUpdated_ = true;
112 }
113 
114 void RSCanvasNode::DrawOnNode(RSModifierType type, DrawFunc func)
115 {
116 #ifndef USE_ROSEN_DRAWING
117     auto recordingCanvas = std::make_shared<RSRecordingCanvas>(GetPaintWidth(), GetPaintHeight());
118     recordingCanvas->SetIsCustomTextType(isCustomTextType_);
119 #else
120     auto recordingCanvas = std::make_shared<ExtendRecordingCanvas>(GetPaintWidth(), GetPaintHeight());
121     recordingCanvas->SetIsCustomTextType(isCustomTextType_);
122 #endif
123     func(recordingCanvas);
124     auto transactionProxy = RSTransactionProxy::GetInstance();
125     if (transactionProxy == nullptr) {
126         return;
127     }
128     auto recording = recordingCanvas->GetDrawCmdList();
129 #ifndef USE_ROSEN_DRAWING
130     if (recording && recording->GetSize() == 0) {
131 #else
132     if (recording && recording->IsEmpty()) {
133 #endif
134         return;
135     }
136     if (recording != nullptr && RSSystemProperties::GetDrawTextAsBitmap()) {
137         // replace drawOpItem with cached one (generated by CPU)
138         recording->GenerateCache();
139     }
140     std::unique_ptr<RSCommand> command =
141         std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording, static_cast<uint16_t>(type));
142     transactionProxy->AddCommand(command, IsRenderServiceNode());
143     recordingUpdated_ = true;
144 }
145 
146 float RSCanvasNode::GetPaintWidth() const
147 {
148     auto frame = GetStagingProperties().GetFrame();
149     return frame.z_ <= 0.f ? GetStagingProperties().GetBounds().z_ : frame.z_;
150 }
151 
152 float RSCanvasNode::GetPaintHeight() const
153 {
154     auto frame = GetStagingProperties().GetFrame();
155     return frame.w_ <= 0.f ? GetStagingProperties().GetBounds().w_ : frame.w_;
156 }
157 
158 void RSCanvasNode::SetFreeze(bool isFreeze)
159 {
160     if (!IsUniRenderEnabled()) {
161         ROSEN_LOGE("SetFreeze is not supported in separate render");
162         return;
163     }
164     std::unique_ptr<RSCommand> command = std::make_unique<RSSetFreeze>(GetId(), isFreeze);
165     auto transactionProxy = RSTransactionProxy::GetInstance();
166     if (transactionProxy != nullptr) {
167         transactionProxy->AddCommand(command, true);
168     }
169 }
170 
171 void RSCanvasNode::OnBoundsSizeChanged() const
172 {
173     auto bounds = GetStagingProperties().GetBounds();
174     std::lock_guard<std::mutex> lock(mutex_);
175     if (boundsChangedCallback_) {
176         boundsChangedCallback_(bounds);
177     }
178 }
179 
180 void RSCanvasNode::SetBoundsChangedCallback(BoundsChangedCallback callback)
181 {
182   std::lock_guard<std::mutex> lock(mutex_);
183   boundsChangedCallback_ = callback;
184 }
185 
186 } // namespace Rosen
187 } // namespace OHOS
188