1 /*
2 * Copyright (c) 2021 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 <algorithm>
17 #include <iostream>
18 #include <surface.h>
19 #include <cmath>
20 #include <securec.h>
21
22 #include "command/rs_base_node_command.h"
23 #include "command/rs_display_node_command.h"
24 #include "command/rs_surface_node_command.h"
25 #include "common/rs_common_def.h"
26 #include "pipeline/rs_render_result.h"
27 #include "pipeline/rs_render_thread.h"
28 #include "ui/rs_node.h"
29 #include "ui/rs_surface_extractor.h"
30 #include "ui/rs_ui_director.h"
31 #include "core/transaction/rs_interfaces.h"
32 #include "core/ui/rs_display_node.h"
33 #include "core/ui/rs_surface_node.h"
34 // temporary debug
35 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_frame_ohos.h"
36 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_ohos.h"
37
38 #include "drawing_canvas.h"
39 #include "drawing_color.h"
40 #include "drawing_bitmap.h"
41 #include "drawing_path.h"
42 #include "drawing_pen.h"
43 #include "drawing_brush.h"
44 #include "drawing_types.h"
45
46 #include "utils/log.h"
47
48 using namespace OHOS;
49 using namespace Media;
50 using namespace Rosen;
51 using namespace std;
52
53 using TestFunc = std::function<void(OH_Drawing_Canvas*, uint32_t, uint32_t)>;
54 static std::vector<TestFunc> testFuncVec;
55 constexpr static int32_t WIDTH = 720;
56 constexpr static int32_t HEIGHT = 1280;
57
TestDrawPathPro(OH_Drawing_Canvas * cCanvas,uint32_t width,uint32_t height)58 static void TestDrawPathPro(OH_Drawing_Canvas* cCanvas, uint32_t width, uint32_t height)
59 {
60 LOGI("+++++++ TestDrawPathPro");
61 // 300 means length of pentagram border
62 int len = 300;
63
64 // point a position
65 float aX = 500;
66 float aY = 500;
67
68 // point d position, 18 means degree of pentagram
69 float dX = aX - len * std::sin(18.0f);
70 float dY = aY + len * std::cos(18.0f);
71
72 // point c position, 18 means degree of pentagram
73 float cX = aX + len * std::sin(18.0f);
74 float cY = dY;
75
76 // point b position
77 float bX = aX + (len / 2.0);
78 float bY = aY + std::sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0));
79
80 // point e position
81 float eX = aX - (len / 2.0);
82 float eY = bY;
83
84 OH_Drawing_Path* cPath = OH_Drawing_PathCreate();
85 OH_Drawing_PathMoveTo(cPath, aX, aY);
86 OH_Drawing_PathLineTo(cPath, bX, bY);
87 OH_Drawing_PathLineTo(cPath, cX, cY);
88 OH_Drawing_PathLineTo(cPath, dX, dY);
89 OH_Drawing_PathLineTo(cPath, eX, eY);
90 OH_Drawing_PathClose(cPath);
91
92 OH_Drawing_Pen* cPen = OH_Drawing_PenCreate();
93 OH_Drawing_PenSetAntiAlias(cPen, true);
94 OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
95 // 10.0 means pentagram border line width
96 OH_Drawing_PenSetWidth(cPen, 10.0);
97 OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN);
98 OH_Drawing_CanvasAttachPen(cCanvas, cPen);
99
100 OH_Drawing_Brush* cBrush = OH_Drawing_BrushCreate();
101 OH_Drawing_BrushSetColor(cBrush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00));
102 OH_Drawing_CanvasAttachBrush(cCanvas, cBrush);
103
104 OH_Drawing_CanvasDrawPath(cCanvas, cPath);
105
106 // (500, 500) means start position of line
107 float lineStartX = 500;
108 float lineStartY = 500;
109
110 // (500, 1000) means end position of line
111 float lineEndX = 500;
112 float lineEndY = 1000;
113
114 // 20.0 means line width
115 OH_Drawing_PenSetWidth(cPen, 20.0);
116 OH_Drawing_PenSetCap(cPen, LINE_ROUND_CAP);
117 OH_Drawing_CanvasAttachPen(cCanvas, cPen);
118 OH_Drawing_CanvasDetachBrush(cCanvas);
119 OH_Drawing_CanvasDrawLine(cCanvas, lineStartX, lineStartY, lineEndX, lineEndY);
120
121 OH_Drawing_BrushDestroy(cBrush);
122 OH_Drawing_PenDestroy(cPen);
123 OH_Drawing_PathDestroy(cPath);
124 LOGI("+++++++ TestDrawPathPro");
125 }
126
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,size_t index)127 static void DoDraw(uint8_t *addr, uint32_t width, uint32_t height, size_t index)
128 {
129 OH_Drawing_Bitmap* cBitmap = OH_Drawing_BitmapCreate();
130 OH_Drawing_BitmapFormat cFormat {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
131 OH_Drawing_BitmapBuild(cBitmap, width, height, &cFormat);
132
133 OH_Drawing_Canvas* cCanvas = OH_Drawing_CanvasCreate();
134 OH_Drawing_CanvasBind(cCanvas, cBitmap);
135
136 OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
137
138 testFuncVec[index](cCanvas, width, height);
139
140 // 4 means stride
141 constexpr uint32_t stride = 4;
142 uint32_t addrSize = width * height * stride;
143 void* bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap);
144 std::copy(addr, addr + addrSize, static_cast<uint8_t*>(bitmapAddr));
145 OH_Drawing_CanvasDestroy(cCanvas);
146 OH_Drawing_BitmapDestroy(cBitmap);
147 }
148
DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t width,int32_t height,size_t index)149 static void DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height, size_t index)
150 {
151 sptr<Surface> surface = surfaceNode->GetSurface();
152 if (surface == nullptr) {
153 return;
154 }
155
156 sptr<SurfaceBuffer> buffer;
157 int32_t releaseFence;
158 BufferRequestConfig config = {
159 .width = width,
160 .height = height,
161 .strideAlignment = 0x8,
162 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
163 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
164 };
165
166 SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
167 LOGI("request buffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
168
169 if (buffer == nullptr) {
170 LOGE("request buffer failed: buffer is nullptr");
171 return;
172 }
173 if (buffer->GetVirAddr() == nullptr) {
174 LOGE("get virAddr failed: virAddr is nullptr");
175 return;
176 }
177
178 auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
179 LOGI("buffer width:%{public}d, height:%{public}d", buffer->GetWidth(), buffer->GetHeight());
180 DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), index);
181
182 BufferFlushConfig flushConfig = {
183 .damage = {
184 .w = buffer->GetWidth(),
185 .h = buffer->GetHeight(),
186 },
187 };
188 ret = surface->FlushBuffer(buffer, -1, flushConfig);
189 LOGI("flushBuffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
190 }
191
CreateSurface()192 static std::shared_ptr<RSSurfaceNode> CreateSurface()
193 {
194 RSSurfaceNodeConfig config;
195 return RSSurfaceNode::Create(config);
196 }
197
main()198 int main()
199 {
200 testFuncVec.push_back(TestDrawPathPro);
201 auto surfaceNode = CreateSurface();
202 RSDisplayNodeConfig config;
203 RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
204 for (size_t i = 0; i < testFuncVec.size(); i++) {
205 auto transactionProxy = RSTransactionProxy::GetInstance();
206 if (transactionProxy == nullptr) {
207 continue;
208 }
209 // sleep 2s
210 sleep(2);
211 displayNode->AddChild(surfaceNode, -1);
212 surfaceNode->SetBounds(0, 0, WIDTH, HEIGHT);
213 transactionProxy->FlushImplicitTransaction();
214 DrawSurface(surfaceNode, WIDTH, HEIGHT, i);
215 // sleep 8s
216 sleep(8);
217 displayNode->RemoveChild(surfaceNode);
218 transactionProxy->FlushImplicitTransaction();
219 }
220 return 0;
221 }
222