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
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30 constexpr int EDGE_WIDTH_LIMIT = 1000;
31 }
RSCanvasDrawingNode(bool isRenderServiceNode,bool isTextureExportNode)32 RSCanvasDrawingNode::RSCanvasDrawingNode(bool isRenderServiceNode, bool isTextureExportNode)
33 : RSCanvasNode(isRenderServiceNode, isTextureExportNode) {}
34
~RSCanvasDrawingNode()35 RSCanvasDrawingNode::~RSCanvasDrawingNode() {}
36
Create(bool isRenderServiceNode,bool isTextureExportNode)37 RSCanvasDrawingNode::SharedPtr RSCanvasDrawingNode::Create(bool isRenderServiceNode, bool isTextureExportNode)
38 {
39 SharedPtr node(new RSCanvasDrawingNode(isRenderServiceNode, isTextureExportNode));
40 RSNodeMap::MutableInstance().RegisterNode(node);
41
42 auto transactionProxy = RSTransactionProxy::GetInstance();
43 if (!transactionProxy) {
44 return node;
45 }
46
47 std::unique_ptr<RSCommand> command =
48 std::make_unique<RSCanvasDrawingNodeCreate>(node->GetId(), isTextureExportNode);
49 transactionProxy->AddCommand(command, node->IsRenderServiceNode());
50 return node;
51 }
52
ResetSurface(int width,int height)53 bool RSCanvasDrawingNode::ResetSurface(int width, int height)
54 {
55 auto transactionProxy = RSTransactionProxy::GetInstance();
56 if (!transactionProxy) {
57 return false;
58 }
59 if (width > EDGE_WIDTH_LIMIT) {
60 ROSEN_LOGI("RSCanvasDrawingNode::ResetSurface id:%{public}" PRIu64 " width:%{public}d height:%{public}d",
61 GetId(), width, height);
62 }
63 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeResetSurface>(GetId(), width, height);
64 transactionProxy->AddCommand(command, IsRenderServiceNode());
65 return true;
66 }
67
CreateRenderNodeForTextureExportSwitch()68 void RSCanvasDrawingNode::CreateRenderNodeForTextureExportSwitch()
69 {
70 auto transactionProxy = RSTransactionProxy::GetInstance();
71 if (transactionProxy == nullptr) {
72 return;
73 }
74 std::unique_ptr<RSCommand> command = std::make_unique<RSCanvasDrawingNodeCreate>(GetId(), isTextureExportNode_);
75 if (IsRenderServiceNode()) {
76 hasCreateRenderNodeInRS_ = true;
77 } else {
78 hasCreateRenderNodeInRT_ = true;
79 }
80 transactionProxy->AddCommand(command, IsRenderServiceNode());
81 }
82
GetBitmap(Drawing::Bitmap & bitmap,std::shared_ptr<Drawing::DrawCmdList> drawCmdList,const Drawing::Rect * rect)83 bool RSCanvasDrawingNode::GetBitmap(Drawing::Bitmap& bitmap,
84 std::shared_ptr<Drawing::DrawCmdList> drawCmdList, const Drawing::Rect* rect)
85 {
86 if (IsUniRenderEnabled()) {
87 auto renderServiceClient =
88 std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
89 if (renderServiceClient == nullptr) {
90 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap renderServiceClient is nullptr!");
91 return false;
92 }
93 bool ret = renderServiceClient->GetBitmap(GetId(), bitmap);
94 if (!ret) {
95 ROSEN_LOGE("RSCanvasDrawingNode::GetBitmap GetBitmap failed");
96 return ret;
97 }
98 } else {
99 auto node =
100 RSRenderThread::Instance().GetContext().GetNodeMap().GetRenderNode<RSCanvasDrawingRenderNode>(GetId());
101 if (node == nullptr) {
102 RS_LOGE("RSCanvasDrawingNode::GetBitmap cannot find NodeId: [%{public}" PRIu64 "]", GetId());
103 return false;
104 }
105 if (node->GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE) {
106 RS_LOGE("RSCanvasDrawingNode::GetBitmap RenderNodeType != RSRenderNodeType::CANVAS_DRAWING_NODE");
107 return false;
108 }
109 auto getBitmapTask = [&node, &bitmap]() { bitmap = node->GetBitmap(); };
110 RSRenderThread::Instance().PostSyncTask(getBitmapTask);
111 if (bitmap.IsValid()) {
112 return false;
113 }
114 }
115 if (drawCmdList == nullptr) {
116 RS_LOGD("RSCanvasDrawingNode::GetBitmap drawCmdList == nullptr");
117 } else {
118 Drawing::Canvas canvas;
119 canvas.Bind(bitmap);
120 drawCmdList->Playback(canvas, rect);
121 }
122 return true;
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 (IsUniRenderEnabled()) {
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