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 "platform/common/rs_log.h"
24 #include "common/rs_obj_geometry.h"
25 #include "pipeline/rs_draw_cmd_list.h"
26 #include "pipeline/rs_node_map.h"
27 #include "transaction/rs_transaction_proxy.h"
28
29 namespace OHOS {
30 namespace Rosen {
Create(bool isRenderServiceNode)31 RSCanvasNode::SharedPtr RSCanvasNode::Create(bool isRenderServiceNode)
32 {
33 SharedPtr node(new RSCanvasNode(isRenderServiceNode));
34 RSNodeMap::MutableInstance().RegisterNode(node);
35
36 auto transactionProxy = RSTransactionProxy::GetInstance();
37 if (transactionProxy == nullptr) {
38 return node;
39 }
40 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasNodeCreate>(node->GetId());
41 transactionProxy->AddCommand(command, node->IsRenderServiceNode());
42 if (node->NeedSendExtraCommand()) {
43 std::unique_ptr<RSCommand> extraCommand = std::make_unique<RSCanvasNodeCreate>(node->GetId());
44 transactionProxy->AddCommand(extraCommand, !node->IsRenderServiceNode());
45 }
46 return node;
47 }
48
RSCanvasNode(bool isRenderServiceNode)49 RSCanvasNode::RSCanvasNode(bool isRenderServiceNode) : RSNode(isRenderServiceNode) {}
50
~RSCanvasNode()51 RSCanvasNode::~RSCanvasNode()
52 {
53 DrawCmdListManager::Instance().ClearDrawCmdList(GetId());
54 }
55
BeginRecording(int width,int height)56 SkCanvas* RSCanvasNode::BeginRecording(int width, int height)
57 {
58 recordingCanvas_ = new RSRecordingCanvas(width, height);
59 DrawCmdListManager::Instance().ClearDrawCmdList(GetId());
60 auto transactionProxy = RSTransactionProxy::GetInstance();
61 if (transactionProxy == nullptr) {
62 return recordingCanvas_;
63 }
64 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasNodeClearRecording>(GetId());
65 transactionProxy->AddCommand(command, IsRenderServiceNode());
66 if (NeedSendExtraCommand()) {
67 std::unique_ptr<RSCommand> extraCommand = std::make_unique<RSCanvasNodeClearRecording>(GetId());
68 transactionProxy->AddCommand(extraCommand, !IsRenderServiceNode());
69 }
70 return recordingCanvas_;
71 }
72
IsRecording() const73 bool RSCanvasNode::IsRecording() const
74 {
75 return recordingCanvas_ != nullptr;
76 }
77
FinishRecording()78 void RSCanvasNode::FinishRecording()
79 {
80 if (!IsRecording()) {
81 ROSEN_LOGW("RSCanvasNode::FinishRecording, IsRecording = false");
82 return;
83 }
84 auto recording = static_cast<RSRecordingCanvas*>(recordingCanvas_)->GetDrawCmdList();
85 delete recordingCanvas_;
86 recordingCanvas_ = nullptr;
87 DrawCmdListManager::Instance().RegisterDrawCmdList(GetId(), recording);
88 auto transactionProxy = RSTransactionProxy::GetInstance();
89 if (transactionProxy == nullptr) {
90 return;
91 }
92 std::unique_ptr<RSCommand> command =
93 std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording,
94 drawContentLast_ ? static_cast<uint16_t>(RSModifierType::FOREGROUND_STYLE)
95 : static_cast<uint16_t>(RSModifierType::CONTENT_STYLE));
96 transactionProxy->AddCommand(command, IsRenderServiceNode());
97 if (NeedSendExtraCommand()) {
98 std::unique_ptr<RSCommand> extraCommand = std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording,
99 drawContentLast_ ? static_cast<uint16_t>(RSModifierType::FOREGROUND_STYLE)
100 : static_cast<uint16_t>(RSModifierType::CONTENT_STYLE));
101 transactionProxy->AddCommand(extraCommand, !IsRenderServiceNode());
102 }
103 }
104
DrawOnNode(RSModifierType type,DrawFunc func)105 void RSCanvasNode::DrawOnNode(RSModifierType type, DrawFunc func)
106 {
107 auto recordingCanvas = std::make_shared<RSRecordingCanvas>(GetPaintWidth(), GetPaintHeight());
108 func(recordingCanvas);
109 auto transactionProxy = RSTransactionProxy::GetInstance();
110 if (transactionProxy == nullptr) {
111 return;
112 }
113 auto recording = recordingCanvas->GetDrawCmdList();
114 DrawCmdListManager::Instance().RegisterDrawCmdList(GetId(), recording);
115 std::unique_ptr<RSCommand> command =
116 std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording, static_cast<uint16_t>(type));
117 transactionProxy->AddCommand(command, IsRenderServiceNode());
118 if (NeedSendExtraCommand()) {
119 std::unique_ptr<RSCommand> extraCommand =
120 std::make_unique<RSCanvasNodeUpdateRecording>(GetId(), recording, static_cast<uint16_t>(type));
121 transactionProxy->AddCommand(extraCommand, !IsRenderServiceNode());
122 }
123 }
124
GetPaintWidth() const125 float RSCanvasNode::GetPaintWidth() const
126 {
127 auto frame = GetStagingProperties().GetFrame();
128 return frame.z_ <= 0.f ? GetStagingProperties().GetBounds().z_ : frame.z_;
129 }
130
GetPaintHeight() const131 float RSCanvasNode::GetPaintHeight() const
132 {
133 auto frame = GetStagingProperties().GetFrame();
134 return frame.w_ <= 0.f ? GetStagingProperties().GetBounds().w_ : frame.w_;
135 }
136 } // namespace Rosen
137 } // namespace OHOS
138