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 node->SetUIContextToken();
51 return node;
52 }
53
ResetSurface(int width,int height)54 bool RSCanvasDrawingNode::ResetSurface(int width, int height)
55 {
56 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeResetSurface>(GetId(), width, height);
57 if (AddCommand(command, IsRenderServiceNode())) {
58 return true;
59 }
60 return false;
61 }
62
CreateRenderNodeForTextureExportSwitch()63 void RSCanvasDrawingNode::CreateRenderNodeForTextureExportSwitch()
64 {
65 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeCreate>(GetId(), isTextureExportNode_);
66 if (IsRenderServiceNode()) {
67 hasCreateRenderNodeInRS_ = true;
68 } else {
69 hasCreateRenderNodeInRT_ = true;
70 }
71 AddCommand(command, IsRenderServiceNode());
72 }
73
GetBitmap(Drawing::Bitmap & bitmap,std::shared_ptr<Drawing::DrawCmdList> drawCmdList,const Drawing::Rect * rect)74 bool RSCanvasDrawingNode::GetBitmap(Drawing::Bitmap& bitmap,
75 std::shared_ptr<Drawing::DrawCmdList> drawCmdList, const Drawing::Rect* rect)
76 {
77 if (IsRenderServiceNode()) {
78 auto renderServiceClient =
79 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
80 if (renderServiceClient == nullptr) {
81 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap renderServiceClient is nullptr!");
82 return false;
83 }
84 bool ret = renderServiceClient->GetBitmap(GetId(), bitmap);
85 if (!ret) {
86 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap GetBitmap failed");
87 return ret;
88 }
89 } else {
90 auto node =
91 RSRenderThread::Instance().GetContext().GetNodeMap().GetRenderNode<RSCanvasDrawingRenderNode>(GetId());
92 if (node == nullptr) {
93 RS_LOGE("RSCanvasDrawingNode::GetBitmap cannot find NodeId: [%{public}" PRIu64 "]", GetId());
94 return false;
95 }
96 if (node->GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE) {
97 RS_LOGE("RSCanvasDrawingNode::GetBitmap RenderNodeType != RSRenderNodeType::CANVAS_DRAWING_NODE");
98 return false;
99 }
100 auto getBitmapTask = [&node, &bitmap]() { bitmap = node->GetBitmap(); };
101 RSRenderThread::Instance().PostSyncTask(getBitmapTask);
102 if (bitmap.IsValid()) {
103 return false;
104 }
105 }
106 if (drawCmdList == nullptr) {
107 RS_LOGD("RSCanvasDrawingNode::GetBitmap drawCmdList == nullptr");
108 } else {
109 Drawing::Canvas canvas;
110 canvas.Bind(bitmap);
111 drawCmdList->Playback(canvas, rect);
112 }
113 return true;
114 }
115
RegisterNodeMap()116 void RSCanvasDrawingNode::RegisterNodeMap()
117 {
118 auto rsContext = GetRSUIContext();
119 if (rsContext == nullptr) {
120 return;
121 }
122 auto& nodeMap = rsContext->GetMutableNodeMap();
123 nodeMap.RegisterNode(shared_from_this());
124 }
125
GetPixelmap(std::shared_ptr<Media::PixelMap> pixelmap,std::shared_ptr<Drawing::DrawCmdList> drawCmdList,const Drawing::Rect * rect)126 bool RSCanvasDrawingNode::GetPixelmap(std::shared_ptr<Media::PixelMap> pixelmap,
127 std::shared_ptr<Drawing::DrawCmdList> drawCmdList, const Drawing::Rect* rect)
128 {
129 if (!pixelmap) {
130 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: pixelmap is nullptr");
131 return false;
132 }
133 if (IsRenderServiceNode()) {
134 auto renderServiceClient =
135 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
136 if (renderServiceClient == nullptr) {
137 ROSEN_LOGE("RSCanvasDrawingNode::GetPixelmap: renderServiceClient is nullptr!");
138 return false;
139 }
140 bool ret = renderServiceClient->GetPixelmap(GetId(), pixelmap, rect, drawCmdList);
141 if (!ret || !pixelmap) {
142 ROSEN_LOGD("RSCanvasDrawingNode::GetPixelmap: GetPixelmap failed");
143 return false;
144 }
145 } else {
146 auto node =
147 RSRenderThread::Instance().GetContext().GetNodeMap().GetRenderNode<RSCanvasDrawingRenderNode>(GetId());
148 if (node == nullptr) {
149 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: cannot find NodeId: [%{public}" PRIu64 "]", GetId());
150 return false;
151 }
152 if (node->GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE) {
153 RS_LOGE("RSCanvasDrawingNode::GetPixelmap: RenderNodeType != RSRenderNodeType::CANVAS_DRAWING_NODE");
154 return false;
155 }
156 bool ret = false;
157 auto getPixelmapTask = [&node, &pixelmap, rect, &ret, &drawCmdList]() {
158 ret = node->GetPixelmap(pixelmap, rect, UINT32_MAX, drawCmdList);
159 };
160 RSRenderThread::Instance().PostSyncTask(getPixelmapTask);
161 if (!ret || !pixelmap) {
162 return false;
163 }
164 }
165 return true;
166 }
167 } // namespace Rosen
168 } // namespace OHOS