1 /*
2 * Copyright (c) 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_drawing_node.h"
17
18 #include "command/rs_canvas_drawing_node_command.h"
19 #include "common/rs_obj_geometry.h"
20 #include "pipeline/rs_canvas_drawing_render_node.h"
21 #include "pipeline/rs_node_map.h"
22 #include "pipeline/rs_render_thread.h"
23 #include "platform/common/rs_log.h"
24 #include "transaction/rs_render_service_client.h"
25 #include "transaction/rs_transaction_proxy.h"
26 #include "ui/rs_ui_context.h"
27
28 namespace OHOS {
29 namespace Rosen {
RSCanvasDrawingNode(bool isRenderServiceNode,bool isTextureExportNode,std::shared_ptr<RSUIContext> rsUIContext)30 RSCanvasDrawingNode::RSCanvasDrawingNode(
31 bool isRenderServiceNode, bool isTextureExportNode, std::shared_ptr<RSUIContext> rsUIContext)
32 : RSCanvasNode(isRenderServiceNode, isTextureExportNode, rsUIContext)
33 {}
34
~RSCanvasDrawingNode()35 RSCanvasDrawingNode::~RSCanvasDrawingNode() {}
36
Create(bool isRenderServiceNode,bool isTextureExportNode,std::shared_ptr<RSUIContext> rsUIContext)37 RSCanvasDrawingNode::SharedPtr RSCanvasDrawingNode::Create(
38 bool isRenderServiceNode, bool isTextureExportNode, std::shared_ptr<RSUIContext> rsUIContext)
39 {
40 SharedPtr node(new RSCanvasDrawingNode(isRenderServiceNode, isTextureExportNode, rsUIContext));
41 if (rsUIContext != nullptr) {
42 rsUIContext->GetMutableNodeMap().RegisterNode(node);
43 } else {
44 RSNodeMap::MutableInstance().RegisterNode(node);
45 }
46
47 std::unique_ptr<RSCommand> command =
48 std::make_unique<RSCanvasDrawingNodeCreate>(node->GetId(), isTextureExportNode);
49 node->AddCommand(command, node->IsRenderServiceNode());
50 return node;
51 }
52
ResetSurface(int width,int height)53 bool RSCanvasDrawingNode::ResetSurface(int width, int height)
54 {
55 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeResetSurface>(GetId(), width, height);
56 if (AddCommand(command, IsRenderServiceNode())) {
57 return true;
58 }
59 return false;
60 }
61
CreateRenderNodeForTextureExportSwitch()62 void RSCanvasDrawingNode::CreateRenderNodeForTextureExportSwitch()
63 {
64 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeCreate>(GetId(), isTextureExportNode_);
65 if (IsRenderServiceNode()) {
66 hasCreateRenderNodeInRS_ = true;
67 } else {
68 hasCreateRenderNodeInRT_ = true;
69 }
70 AddCommand(command, IsRenderServiceNode());
71 }
72
GetBitmap(Drawing::Bitmap & bitmap,std::shared_ptr<Drawing::DrawCmdList> drawCmdList,const Drawing::Rect * rect)73 bool RSCanvasDrawingNode::GetBitmap(Drawing::Bitmap& bitmap,
74 std::shared_ptr<Drawing::DrawCmdList> drawCmdList, const Drawing::Rect* rect)
75 {
76 if (IsRenderServiceNode()) {
77 auto renderServiceClient =
78 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
79 if (renderServiceClient == nullptr) {
80 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap renderServiceClient is nullptr!");
81 return false;
82 }
83 bool ret = renderServiceClient->GetBitmap(GetId(), bitmap);
84 if (!ret) {
85 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap GetBitmap failed");
86 return ret;
87 }
88 } else {
89 auto node =
90 RSRenderThread::Instance().GetContext().GetNodeMap().GetRenderNode<RSCanvasDrawingRenderNode>(GetId());
91 if (node == nullptr) {
92 RS_LOGE("RSCanvasDrawingNode::GetBitmap cannot find NodeId: [%{public}" PRIu64 "]", GetId());
93 return false;
94 }
95 if (node->GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE) {
96 RS_LOGE("RSCanvasDrawingNode::GetBitmap RenderNodeType != RSRenderNodeType::CANVAS_DRAWING_NODE");
97 return false;
98 }
99 auto getBitmapTask = [&node, &bitmap]() { bitmap = node->GetBitmap(); };
100 RSRenderThread::Instance().PostSyncTask(getBitmapTask);
101 if (bitmap.IsValid()) {
102 return false;
103 }
104 }
105 if (drawCmdList == nullptr) {
106 RS_LOGD("RSCanvasDrawingNode::GetBitmap drawCmdList == nullptr");
107 } else {
108 Drawing::Canvas canvas;
109 canvas.Bind(bitmap);
110 drawCmdList->Playback(canvas, rect);
111 }
112 return true;
113 }
114
RegisterNodeMap()115 void RSCanvasDrawingNode::RegisterNodeMap()
116 {
117 auto rsContext = GetRSUIContext();
118 if (rsContext == nullptr) {
119 return;
120 }
121 auto& nodeMap = rsContext->GetMutableNodeMap();
122 nodeMap.RegisterNode(shared_from_this());
123 }
124
GetPixelmap(std::shared_ptr<Media::PixelMap> pixelmap,std::shared_ptr<Drawing::DrawCmdList> drawCmdList,const Drawing::Rect * rect)125 bool RSCanvasDrawingNode::GetPixelmap(std::shared_ptr<Media::PixelMap> pixelmap,
126 std::shared_ptr<Drawing::DrawCmdList> drawCmdList, const Drawing::Rect* rect)
127 {
128 if (!pixelmap) {
129 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: pixelmap is nullptr");
130 return false;
131 }
132 if (IsRenderServiceNode()) {
133 auto renderServiceClient =
134 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
135 if (renderServiceClient == nullptr) {
136 ROSEN_LOGE("RSCanvasDrawingNode::GetPixelmap: renderServiceClient is nullptr!");
137 return false;
138 }
139 bool ret = renderServiceClient->GetPixelmap(GetId(), pixelmap, rect, drawCmdList);
140 if (!ret || !pixelmap) {
141 ROSEN_LOGD("RSCanvasDrawingNode::GetPixelmap: GetPixelmap failed");
142 return false;
143 }
144 } else {
145 auto node =
146 RSRenderThread::Instance().GetContext().GetNodeMap().GetRenderNode<RSCanvasDrawingRenderNode>(GetId());
147 if (node == nullptr) {
148 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: cannot find NodeId: [%{public}" PRIu64 "]", GetId());
149 return false;
150 }
151 if (node->GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE) {
152 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: RenderNodeType != RSRenderNodeType::CANVAS_DRAWING_NODE");
153 return false;
154 }
155 bool ret = false;
156 auto getPixelmapTask = [&node, &pixelmap, rect, &ret, &drawCmdList]() {
157 ret = node->GetPixelmap(pixelmap, rect);
158 };
159 RSRenderThread::Instance().PostSyncTask(getPixelmapTask);
160 if (!ret || !pixelmap) {
161 return false;
162 }
163 }
164 return true;
165 }
166 } // namespace Rosen
167 } // namespace OHOS