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 <iostream>
17 #include <surface.h>
18 #include <cmath>
19 
20 #include "command/rs_base_node_command.h"
21 #include "command/rs_display_node_command.h"
22 #include "command/rs_surface_node_command.h"
23 #include "common/rs_common_def.h"
24 #include "display_type.h"
25 #include "pipeline/rs_render_result.h"
26 #include "pipeline/rs_render_thread.h"
27 #include "ui/rs_node.h"
28 #include "ui/rs_surface_extractor.h"
29 #include "ui/rs_ui_director.h"
30 #include "core/transaction/rs_interfaces.h"
31 #include "core/ui/rs_display_node.h"
32 #include "core/ui/rs_surface_node.h"
33 // temporary debug
34 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_frame_ohos.h"
35 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_ohos.h"
36 
37 #include "draw/color.h"
38 
39 #include "image/bitmap.h"
40 #include "image/image.h"
41 #include "image/picture.h"
42 
43 #include "draw/brush.h"
44 #include "draw/canvas.h"
45 #include "draw/pen.h"
46 #include "draw/path.h"
47 #include "draw/clip.h"
48 #include "effect/path_effect.h"
49 #include "effect/shader_effect.h"
50 #include "utils/rect.h"
51 
52 #include "utils/matrix.h"
53 #include "utils/camera3d.h"
54 
55 #include "image_type.h"
56 #include "pixel_map.h"
57 
58 using namespace OHOS;
59 using namespace Media;
60 using namespace Rosen;
61 using namespace Drawing;
62 using namespace std;
63 
64 using TestFunc = std::function<void(Canvas&, uint32_t, uint32_t)>;
65 namespace {
66 #define LOG(fmt, ...) ::OHOS::HiviewDFX::HiLog::Info(             \
67     ::OHOS::HiviewDFX::HiLogLabel {LOG_CORE, 0, "DrawingSampleRS"}, \
68     "%{public}s: " fmt, __func__, ##__VA_ARGS__)
69 }
70 
71 std::vector<TestFunc> testFuncVec;
72 constexpr static int32_t WIDTH = 720;
73 constexpr static int32_t HEIGHT = 1280;
74 
TestDrawPath(Canvas & canvas,uint32_t width,uint32_t height)75 void TestDrawPath(Canvas &canvas, uint32_t width, uint32_t height)
76 {
77     LOGI("+++++++ TestDrawPath");
78     Path path1;
79     // Add beginning of contour at point {200, 200}.
80     path1.MoveTo(200, 200);
81     // Add quad from last point towards (600, 200), to (600, 600).
82     path1.QuadTo(600, 200, 600, 600);
83     path1.Close();
84 
85     Pen pen;
86     pen.SetAntiAlias(true);
87     pen.SetColor(Drawing::Color::COLOR_GRAY);
88     pen.SetWidth(10); // The thickness of the pen is 10
89     canvas.AttachPen(pen);
90 
91     Brush brush;
92     brush.SetColor(Drawing::Color::COLOR_BLUE);
93     canvas.AttachBrush(brush);
94 
95     Path path2;
96     // Add oval to path, bounds of ellipse added is {200, 200, 600, 1000}.
97     path2.AddOval({200, 200, 600, 1000});
98 
99     Path dest;
100     dest.Op(path1, path2, PathOp::UNION);
101     canvas.DrawPath(dest);
102     LOGI("+++++++ TestDrawPath");
103 }
104 
TestDrawPathPro(Canvas & canvas,uint32_t width,uint32_t height)105 void TestDrawPathPro(Canvas &canvas, uint32_t width, uint32_t height)
106 {
107     LOGI("+++++++ TestDrawPathPro");
108     int len = 300;
109     Point a(500, 500); // point at {500, 500}
110 
111     Point c;
112     Point d;
113 
114     d.SetX(a.GetX() - len * std::sin(18.0f));
115     d.SetY(a.GetY() + len * std::cos(18.0f));
116 
117     c.SetX(a.GetX() + len * std::sin(18.0f));
118     c.SetY(d.GetY());
119 
120     Point b;
121     b.SetX(a.GetX() + (len / 2.0));
122     b.SetY(a.GetY() + std::sqrt((c.GetX() - d.GetX()) * (c.GetX() - d.GetX()) + (len / 2.0) * (len / 2.0)));
123 
124     Point e;
125     e.SetX(a.GetX() - (len / 2.0));
126     e.SetY(b.GetY());
127 
128     Path path;
129     path.MoveTo(a.GetX(), a.GetY());
130     path.LineTo(b.GetX(), b.GetY());
131     path.LineTo(c.GetX(), c.GetY());
132     path.LineTo(d.GetX(), d.GetY());
133     path.LineTo(e.GetX(), e.GetY());
134     path.Close();
135 
136     Pen pen;
137     pen.SetAntiAlias(true);
138     pen.SetColor(Drawing::Color::COLOR_RED);
139     pen.SetWidth(10); // The thickness of the pen is 10
140     canvas.AttachPen(pen);
141 
142     Brush brush;
143     brush.SetColor(Drawing::Color::COLOR_BLUE);
144     canvas.AttachBrush(brush);
145 
146     canvas.AttachPen(pen).AttachBrush(brush).DrawPath(path);
147     LOGI("+++++++ TestDrawPathPro");
148 }
149 
TestDrawBase(Canvas & canvas,uint32_t width,uint32_t height)150 void TestDrawBase(Canvas &canvas, uint32_t width, uint32_t height)
151 {
152     LOGI("+++++++ TestDrawBase");
153 
154     Pen pen;
155     pen.SetAntiAlias(true);
156     pen.SetColor(Drawing::Color::COLOR_RED);
157     canvas.AttachPen(pen);
158 
159     // Draw line segment from Point(0, 0) to Point(width, height)
160     canvas.DrawLine(Point(0, 0), Point(width, height));
161 
162     pen.Reset();
163     pen.SetColor(Drawing::Color::COLOR_RED);
164     pen.SetWidth(100); // The thickness of the pen is 100
165     Point point;
166     point.SetX(width / 2.0);
167     point.SetY(height / 2.0);
168     canvas.AttachPen(pen);
169     canvas.DrawPoint(point);
170 
171     Brush brush;
172     brush.SetColor(Drawing::Color::COLOR_BLUE);
173     brush.Reset();
174     canvas.AttachBrush(brush);
175     canvas.DrawRect({1200, 100, 1500, 700}); // rect is set to (fLeft, fTop, fRight, fBottom)
176     LOGI("------- TestDrawBase");
177 }
178 
TestDrawPathEffect(Canvas & canvas,uint32_t width,uint32_t height)179 void TestDrawPathEffect(Canvas &canvas, uint32_t width, uint32_t height)
180 {
181     LOGI("+++++++ TestDrawPathEffect");
182 
183     Pen pen;
184     pen.SetAntiAlias(true);
185     pen.SetColor(Drawing::Color::COLOR_RED);
186     pen.SetWidth(10); // The thickness of the pen is 10
187     scalar vals[] = {10.0, 20.0};
188     // Number of elements in the intervals array is 2; offset into the intervals array is 25.
189     pen.SetPathEffect(PathEffect::CreateDashPathEffect(vals, 2, 25));
190     canvas.AttachPen(pen);
191 
192     Brush brush;
193     brush.SetColor(Drawing::Color::COLOR_BLUE);
194     canvas.AttachBrush(brush);
195     canvas.DrawRect({1200, 300, 1500, 600}); // rect is set to (fLeft, fTop, fRight, fBottom)
196 
197     canvas.DetachPen();
198     canvas.DrawRect({1200, 700, 1500, 1000}); // rect is set to (fLeft, fTop, fRight, fBottom)
199     LOGI("------- TestDrawPathEffect");
200 }
201 
TestDrawFilter(Canvas & canvas,uint32_t width,uint32_t height)202 void TestDrawFilter(Canvas &canvas, uint32_t width, uint32_t height)
203 {
204     LOGI("+++++++ TestDrawFilter");
205 
206     Pen pen;
207     pen.SetAntiAlias(true);
208     pen.SetColor(Drawing::Color::COLOR_BLUE);
209     pen.SetColor(pen.GetColor4f(), Drawing::ColorSpace::CreateSRGBLinear());
210     pen.SetAlpha(0x44); // alpha value is 0x44
211     pen.SetWidth(10); // The thickness of the pen is 10
212     Filter filter;
213     filter.SetColorFilter(ColorFilter::CreateBlendModeColorFilter(Drawing::Color::COLOR_RED, BlendMode::SRC_ATOP));
214     // Sigma value of the Gaussian blur to apply is 10.
215     filter.SetMaskFilter(MaskFilter::CreateBlurMaskFilter(BlurType::NORMAL, 10));
216     pen.SetFilter(filter);
217     canvas.AttachPen(pen);
218 
219     Brush brush;
220     brush.SetColor(Drawing::Color::COLOR_BLUE);
221     brush.SetColor(brush.GetColor4f(), Drawing::ColorSpace::CreateSRGBLinear());
222     brush.SetAlpha(0x44); // alpha value is 0x44
223     brush.SetBlendMode(BlendMode::SRC_ATOP);
224     brush.SetFilter(filter);
225     canvas.AttachBrush(brush);
226     canvas.DrawRect({1200, 300, 1500, 600}); // rect is set to (fLeft, fTop, fRight, fBottom)
227 
228     canvas.DetachPen();
229     canvas.DrawRect({1200, 700, 1500, 1000}); // rect is set to (fLeft, fTop, fRight, fBottom)
230     LOGI("------- TestDrawFilter");
231 }
232 
TestDrawBitmap(Canvas & canvas,uint32_t width,uint32_t height)233 void TestDrawBitmap(Canvas &canvas, uint32_t width, uint32_t height)
234 {
235     LOGI("+++++++ TestDrawBitmap");
236     Bitmap bmp;
237     BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
238     bmp.Build(200, 200, format); // bitmap width and height
239     bmp.ClearWithColor(Drawing::Color::COLOR_BLUE);
240 
241     Pen pen;
242     pen.SetAntiAlias(true);
243     pen.SetColor(Drawing::Color::COLOR_BLUE);
244     pen.SetWidth(10); // The thickness of the pen is 10
245     canvas.AttachPen(pen);
246     canvas.DrawBitmap(bmp, 500, 500);
247 
248     LOGI("------- TestDrawBitmap");
249 }
250 
TestDrawImage(Canvas & canvas,uint32_t width,uint32_t height)251 void TestDrawImage(Canvas& canvas, uint32_t width, uint32_t height)
252 {
253     LOGI("+++++++ TestDrawImage");
254     Bitmap bmp;
255     BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
256     bmp.Build(300, 300, format); // bitmap width and height
257     bmp.ClearWithColor(Drawing::Color::COLOR_BLUE);
258 
259     Image image;
260     image.BuildFromBitmap(bmp);
261     int imageWidth = image.GetWidth();
262     int imageHeight = image.GetHeight();
263     LOGI("image width = %{public}d, image height = %{public}d", imageWidth, imageHeight);
264     Matrix matrix;
265     // Set matrix to rotate by degrees 45 about a pivot point at (0, 0).
266     matrix.Rotate(45, 0, 0);
267     SamplingOptions sampling = SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST);
268     auto e = ShaderEffect::CreateImageShader(image, TileMode::REPEAT, TileMode::MIRROR, sampling, matrix);
269     LOGI("sampling useCubic = %{public}d, filter = %{public}d, mipmap = %{public}d",
270         sampling.GetUseCubic(), sampling.GetFilterMode(), sampling.GetMipmapMode());
271     auto c = Drawing::ColorSpace::CreateRefImage(image);
272 
273     Pen pen;
274     pen.SetAntiAlias(true);
275     pen.SetColor(Drawing::Color::COLOR_BLUE);
276     pen.SetColor(pen.GetColor4f(), c);
277     pen.SetWidth(10); // The thickness of the pen is 10
278     pen.SetShaderEffect(e);
279     canvas.AttachPen(pen);
280     canvas.DrawImage(image, 500, 500, sampling); // Draw image at (500,500)
281 
282     LOGI("------- TestDrawImage");
283 }
284 
TestDrawImageRect(Canvas & canvas,uint32_t width,uint32_t height)285 void TestDrawImageRect(Canvas& canvas, uint32_t width, uint32_t height)
286 {
287     LOGI("+++++++ TestDrawImageRect");
288     Bitmap bmp;
289     BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
290     bmp.Build(300, 300, format); // bitmap width and height
291     bmp.ClearWithColor(Drawing::Color::COLOR_BLUE);
292 
293     Image image;
294     image.BuildFromBitmap(bmp);
295     Drawing::Rect r1(100, 100, 200, 200); // rect is set to (fLeft, fTop, fRight, fBottom)
296     Drawing::Rect r2(300, 300, 500, 500);
297     SamplingOptions sampling = SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST);
298 
299     Brush brush;
300     brush.SetColor(Drawing::Color::COLOR_RED);
301     canvas.AttachBrush(brush);
302     canvas.DrawImageRect(image, r1, r2, sampling, SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
303 
304     LOGI("------- TestDrawImageRect");
305 }
306 
TestPicture(Canvas & canvas,uint32_t width,uint32_t height)307 void TestPicture(Canvas& canvas, uint32_t width, uint32_t height)
308 {
309     LOGI("+++++++ TestPicture");
310     Image image;
311     Picture picture;
312     Matrix matrix;
313     auto srgbColorSpace = Drawing::ColorSpace::CreateSRGB();
314 
315     Brush brush;
316     brush.SetColor(Drawing::Color::COLOR_BLUE);
317     // Created image width and height are set by {50, 50}
318     image.BuildFromPicture(picture, {50, 50}, matrix, brush, BitDepth::KU8, srgbColorSpace);
319 
320     Drawing::Rect rect(1000, 0, 1300, 300); // The tile rectangle size in picture coordinates.
321     auto e = ShaderEffect::CreatePictureShader(picture, TileMode::REPEAT, TileMode::MIRROR,
322         FilterMode::NEAREST, matrix, rect);
323     Pen pen;
324     pen.SetAntiAlias(true);
325     pen.SetColor(Drawing::Color::COLOR_BLUE);
326     pen.SetWidth(10); // The thickness of the pen is 10
327     pen.SetShaderEffect(e);
328     canvas.AttachPen(pen);
329     canvas.DrawPicture(picture);
330 
331     LOGI("------- TestPicture");
332 }
333 
TestMatrix(Canvas & canvas,uint32_t width,uint32_t height)334 void TestMatrix(Canvas &canvas, uint32_t width, uint32_t height)
335 {
336     LOGI("+++++++ TestMatrix");
337     Brush brush;
338     brush.SetColor(Drawing::Color::COLOR_BLUE);
339     canvas.AttachBrush(brush);
340     canvas.DrawRect({1200, 100, 1500, 400}); // rect is set to (fLeft, fTop, fRight, fBottom)
341 
342     brush.SetColor(Drawing::Color::COLOR_RED);
343     canvas.AttachBrush(brush);
344     Matrix m;
345     // Set matrix to scale by 0.5 and 1.5, about a pivot point at (0, 0).
346     m.Scale(0.5, 1.5, 0, 0);
347 
348     canvas.SetMatrix(m);
349     canvas.DrawRect({1000, 0, 1300, 300}); // rect is set to (fLeft, fTop, fRight, fBottom)
350 
351     Matrix n;
352     /* Set matrix to:
353         | 1  0  100 |
354         | 0  1  300 |
355         | 0  0   1  |
356     */
357     n.SetMatrix(1, 0, 100,
358          0, 1, 300,
359          0, 0, 1);
360     brush.SetColor(Drawing::Color::COLOR_GREEN);
361     canvas.AttachBrush(brush);
362     canvas.SetMatrix(n);
363     canvas.DrawRect({1200, 100, 1500, 400}); // rect is set to (fLeft, fTop, fRight, fBottom)
364 
365     Matrix m1;
366     Matrix m2;
367     m1.Translate(100, 300); // Set matrix to translate by (100, 300).
368     // Set matrix to rotate by degrees 45 about a pivot point at (0, 0).
369     m2.Rotate(45, 0, 0);
370     m = m1 * m2;
371 
372     brush.SetColor(Drawing::Color::COLOR_BLACK);
373     canvas.AttachBrush(brush);
374     canvas.SetMatrix(m);
375     canvas.DrawRect({1200, 100, 1500, 400}); // rect is set to (fLeft, fTop, fRight, fBottom)
376 
377     Matrix matrix;
378     matrix.Translate(100, 100); // 100 means offset size
379     std::vector<Point> point = {{0, 0}}; // {0, 0} means point position
380     matrix.MapPoints(point, point, point.size());
381     for (size_t i = 0; i < point.size(); i++) {
382         LOGI("mapped point fx = %{public}f, fy = %{public}f", point[i].GetX(), point[i].GetY());
383     }
384 
385     LOGI("------- TestMatrix");
386 }
387 
TestCamera(Canvas & canvas,uint32_t width,uint32_t height)388 void TestCamera(Canvas &canvas, uint32_t width, uint32_t height)
389 {
390     LOGI("+++++++ TestCamera");
391 
392     Brush brush;
393     Matrix m0;
394     m0.Translate(width / 2.0, height / 2.0); // Set matrix m0 to translate by (width / 2.0, height / 2.0).
395     canvas.SetMatrix(m0);
396 
397     Camera3D camera;
398     camera.RotateXDegrees(-25); // Set camera to rotate by degrees -25 at x-aixs.
399     camera.RotateYDegrees(45); // Set camera to rotate by degrees 45 at y-aixs.
400     camera.Translate(-50, 50, 50); // Set camera to translate by (-50, 50, 50).
401     Drawing::Rect r(0, 0, 500, 500); // rect is set to (fLeft, fTop, fRight, fBottom)
402 
403     canvas.Save();
404     camera.Save();
405     camera.RotateYDegrees(90); // Set camera to rotate by degrees 90 at y-aixs.
406     Matrix m1;
407     camera.ApplyToMatrix(m1);
408     camera.Restore();
409     canvas.ConcatMatrix(m1);
410     brush.SetColor(Drawing::Color::COLOR_LTGRAY);
411     canvas.AttachBrush(brush);
412     canvas.DrawRect(r);
413     canvas.Restore();
414     LOGI("------- TestCamera");
415 }
416 
TestDrawShader(Canvas & canvas,uint32_t width,uint32_t height)417 void TestDrawShader(Canvas &canvas, uint32_t width, uint32_t height)
418 {
419     LOGI("+++++++ TestDrawShader");
420 
421     Brush brush;
422     brush.SetColor(Drawing::Color::COLOR_BLUE);
423     std::vector<ColorQuad> colors{Drawing::Color::COLOR_GREEN, Drawing::Color::COLOR_BLUE, Drawing::Color::COLOR_RED};
424     std::vector<scalar> pos{0.0, 0.5, 1.0};
425     // The start and end points for the gradient: {1200, 700}, {1300, 800}.
426     auto e = ShaderEffect::CreateLinearGradient({1200, 700}, {1300, 800}, colors, pos, TileMode::MIRROR);
427     brush.SetShaderEffect(e);
428 
429     canvas.AttachBrush(brush);
430     canvas.DrawRect({1200, 700, 1500, 1000}); // rect is set to (fLeft, fTop, fRight, fBottom)
431     LOGI("------- TestDrawShader");
432 }
433 
TestDrawShadow(Canvas & canvas,uint32_t width,uint32_t height)434 void TestDrawShadow(Canvas &canvas, uint32_t width, uint32_t height)
435 {
436     LOGI("+++++++ TestDrawShadow");
437 
438     Path path;
439     // Add oval to path, bounds of ellipse added is {200, 200, 600, 1000}.
440     path.AddOval({200, 200, 600, 1000});
441     Point3 planeParams = { 540.0, 0.0, 600.0 };
442     Point3 devLightPos = {0, 0, 0};
443     scalar lightRadius = 0.5;
444     Drawing::Color ambientColor = Drawing::Color::ColorQuadSetARGB(0, 0, 0, 0);
445     Drawing::Color spotColor = Drawing::Color::COLOR_RED;
446     ShadowFlags flag = ShadowFlags::TRANSPARENT_OCCLUDER;
447     canvas.DrawShadow(path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag);
448     LOGI("------- TestDrawShadow");
449 }
450 
TestDrawShadowStyle(Canvas & canvas,uint32_t width,uint32_t height)451 void TestDrawShadowStyle(Canvas &canvas, uint32_t width, uint32_t height)
452 {
453     LOGI("+++++++ TestDrawShadowStyle");
454 
455     Path path;
456     // Add oval to path, bounds of ellipse added is {200, 200, 600, 1000}.
457     path.AddOval({200, 200, 600, 1000});
458     Point3 planeParams = { 540.0, 0.0, 600.0 };
459     Point3 devLightPos = {0, 0, 0};
460     scalar lightRadius = 0.5;
461     Drawing::Color ambientColor = Drawing::Color::ColorQuadSetARGB(0, 0, 0, 0);
462     Drawing::Color spotColor = Drawing::Color::COLOR_RED;
463     ShadowFlags flag = ShadowFlags::TRANSPARENT_OCCLUDER;
464     canvas.DrawShadowStyle(path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag, true);
465     LOGI("------- TestDrawShadowStyle");
466 }
467 
ConstructPixmap()468 std::unique_ptr<PixelMap> ConstructPixmap()
469 {
470     uint32_t pixelMapWidth = 50;
471     uint32_t pixelMapHeight = 50;
472     std::unique_ptr<PixelMap> pixelMap = std::make_unique<PixelMap>();
473     ImageInfo info;
474     info.size.width = pixelMapWidth;
475     info.size.height = pixelMapHeight;
476     info.pixelFormat = Media::PixelFormat::RGBA_8888;
477     info.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
478     info.colorSpace = Media::ColorSpace::SRGB;
479     pixelMap->SetImageInfo(info);
480     LOGI("Constructed pixelMap info: width = %{public}d, height = %{public}d, pixelformat = %{public}d, "
481         "alphatype = %{public}d, colorspace = %{public}d",
482         info.size.width, info.size.height, info.pixelFormat, info.alphaType, info.colorSpace);
483 
484     uint32_t rowDataSize = pixelMapWidth;
485     uint32_t bufferSize = rowDataSize * pixelMapHeight;
486     void *buffer = malloc(bufferSize);
487     if (buffer == nullptr) {
488         LOGE("alloc memory size:[%{public}d] error.", bufferSize);
489         return nullptr;
490     }
491     char *ch = static_cast<char *>(buffer);
492     for (unsigned int i = 0; i < bufferSize; i++) {
493         *(ch++) = static_cast<char>(i);
494     }
495 
496     pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
497 
498     return pixelMap;
499 }
500 
TestDrawPixelmap(Canvas & canvas,uint32_t width,uint32_t height)501 void TestDrawPixelmap(Canvas &canvas, uint32_t width, uint32_t height)
502 {
503     LOGI("+++++++ TestDrawPixelmap");
504     std::unique_ptr<PixelMap> pixelmap = ConstructPixmap();
505 
506     Pen pen;
507     pen.SetAntiAlias(true);
508     pen.SetColor(Drawing::Color::COLOR_BLUE);
509     pen.SetWidth(10); // The thickness of the pen is 10
510     canvas.AttachPen(pen);
511 
512     Brush brush;
513     brush.SetColor(Drawing::Color::COLOR_RED);
514     canvas.AttachBrush(brush);
515 
516     canvas.DrawBitmap(*pixelmap.get(), 500, 500);
517     LOGI("------- TestDrawPixelmap");
518 }
519 
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,size_t index)520 void DoDraw(uint8_t *addr, uint32_t width, uint32_t height, size_t index)
521 {
522     Bitmap bitmap;
523     BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
524     bitmap.Build(width, height, format);
525 
526     Canvas canvas;
527     canvas.Bind(bitmap);
528     canvas.Clear(Drawing::Color::COLOR_WHITE);
529 
530     testFuncVec[index](canvas, width, height);
531 
532     constexpr uint32_t stride = 4;
533     uint32_t addrSize = width * height * stride;
534     auto ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
535     if (ret != EOK) {
536         LOGI("memcpy_s failed");
537     }
538 }
539 
DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t width,int32_t height,size_t index)540 void DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height, size_t index)
541 {
542     sptr<Surface> surface = surfaceNode->GetSurface();
543     if (surface == nullptr) {
544         return;
545     }
546 
547     sptr<SurfaceBuffer> buffer;
548     int32_t releaseFence;
549     BufferRequestConfig config = {
550         .width = width,
551         .height = height,
552         .strideAlignment = 0x8,
553         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
554         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
555     };
556 
557     SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
558     LOGI("request buffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
559 
560     if (buffer == nullptr) {
561         LOGE("request buffer failed: buffer is nullptr");
562         return;
563     }
564     if (buffer->GetVirAddr() == nullptr) {
565         LOGE("get virAddr failed: virAddr is nullptr");
566         return;
567     }
568 
569     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
570     LOGI("buffer width:%{public}d, height:%{public}d", buffer->GetWidth(), buffer->GetHeight());
571     DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), index);
572 
573     BufferFlushConfig flushConfig = {
574         .damage = {
575             .w = buffer->GetWidth(),
576             .h = buffer->GetHeight(),
577         },
578     };
579     ret = surface->FlushBuffer(buffer, -1, flushConfig);
580     LOGI("flushBuffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
581 }
582 
CreateSurface()583 std::shared_ptr<RSSurfaceNode> CreateSurface()
584 {
585     RSSurfaceNodeConfig config;
586     return RSSurfaceNode::Create(config);
587 }
588 
main()589 int main()
590 {
591     testFuncVec.push_back(TestDrawPathPro);
592     testFuncVec.push_back(TestCamera);
593     testFuncVec.push_back(TestDrawBase);
594     testFuncVec.push_back(TestDrawPath);
595     testFuncVec.push_back(TestDrawPathEffect);
596     testFuncVec.push_back(TestDrawBitmap);
597     testFuncVec.push_back(TestDrawImage);
598     testFuncVec.push_back(TestDrawImageRect);
599     testFuncVec.push_back(TestPicture);
600     testFuncVec.push_back(TestDrawFilter);
601     testFuncVec.push_back(TestDrawShader);
602     testFuncVec.push_back(TestDrawShadow);
603     testFuncVec.push_back(TestDrawPixelmap);
604     testFuncVec.push_back(TestMatrix);
605 
606     auto surfaceNode = CreateSurface();
607     RSDisplayNodeConfig config;
608     RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
609     for (size_t i = 0; i < testFuncVec.size(); i++) {
610         auto transactionProxy = RSTransactionProxy::GetInstance();
611         if (transactionProxy == nullptr) {
612             continue;
613         }
614         sleep(2); // wait 2s
615         displayNode->AddChild(surfaceNode, -1);
616         surfaceNode->SetBounds(0, 0, WIDTH, HEIGHT);
617         transactionProxy->FlushImplicitTransaction();
618         DrawSurface(surfaceNode, WIDTH, HEIGHT, i);
619         sleep(4); // wait 4s
620         displayNode->RemoveChild(surfaceNode);
621         transactionProxy->FlushImplicitTransaction();
622     }
623     return 0;
624 }
625