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 "drawing_canvas.h"
17 #include "drawing_color.h"
18 #include "drawing_bitmap.h"
19 #include "drawing_font_collection.h"
20 #include "drawing_text_declaration.h"
21 #include "drawing_types.h"
22 #include "drawing_text_typography.h"
23 
24 #include <securec.h>
25 
26 #include "core/transaction/rs_interfaces.h"
27 #include "utils/log.h"
28 
29 using namespace OHOS;
30 using namespace Media;
31 using namespace Rosen;
32 using namespace std;
33 
34 constexpr static int32_t WIDTH = 720;
35 constexpr static int32_t HEIGHT = 1280;
36 
37 namespace {
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,size_t index)38 void DoDraw(uint8_t *addr, uint32_t width, uint32_t height, size_t index)
39 {
40     OH_Drawing_Bitmap* cBitmap = OH_Drawing_BitmapCreate();
41     OH_Drawing_BitmapFormat cFormat {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
42     OH_Drawing_BitmapBuild(cBitmap, width, height, &cFormat);
43 
44     OH_Drawing_Canvas* cCanvas = OH_Drawing_CanvasCreate();
45     OH_Drawing_CanvasBind(cCanvas, cBitmap);
46     OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
47 
48     OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();
49     OH_Drawing_SetTypographyTextDirection(typoStyle, TEXT_DIRECTION_LTR);
50     OH_Drawing_SetTypographyTextAlign(typoStyle, TEXT_ALIGN_LEFT);
51 
52     OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle,
53         OH_Drawing_CreateFontCollection());
54 
55     OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle();
56     OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
57     double fontSize = 80;
58     OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
59     OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
60     OH_Drawing_SetTextStyleBaseLine(txtStyle, TEXT_BASELINE_ALPHABETIC);
61     OH_Drawing_SetTextStyleFontHeight(txtStyle, 1);
62     const char* fontFamilies[] = {"Roboto"};
63     OH_Drawing_SetTextStyleFontFamilies(txtStyle, 1, fontFamilies);
64     OH_Drawing_SetTextStyleFontStyle(txtStyle, FONT_STYLE_NORMAL);
65     OH_Drawing_SetTextStyleLocale(txtStyle, "en");
66 
67     OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
68 
69     const char* text = "OpenHarmony\n";
70     OH_Drawing_TypographyHandlerAddText(handler, text);
71     OH_Drawing_TypographyHandlerPopTextStyle(handler);
72 
73     OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler);
74     double maxWidth = 800.0;
75     OH_Drawing_TypographyLayout(typography, maxWidth);
76     double position[2] = {10.0, 15.0};
77     OH_Drawing_TypographyPaint(typography, cCanvas, position[0], position[1]);
78 
79     constexpr uint32_t stride = 4;
80     int32_t addrSize = width * height * stride;
81     void* bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap);
82     auto ret = memcpy_s(addr, addrSize, bitmapAddr, addrSize);
83     if (ret != EOK) {
84         LOGI("memcpy_s failed");
85     }
86     OH_Drawing_CanvasDestroy(cCanvas);
87     OH_Drawing_BitmapDestroy(cBitmap);
88     OH_Drawing_DestroyTypographyStyle(typoStyle);
89     OH_Drawing_DestroyTextStyle(txtStyle);
90     OH_Drawing_DestroyTypographyHandler(handler);
91     OH_Drawing_DestroyTypography(typography);
92 }
93 
DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t width,int32_t height,size_t index)94 void DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height, size_t index)
95 {
96     sptr<Surface> surface = surfaceNode->GetSurface();
97     if (surface == nullptr) {
98         return;
99     }
100 
101     sptr<SurfaceBuffer> buffer;
102     int32_t releaseFence;
103     BufferRequestConfig config = {
104         .width = width,
105         .height = height,
106         .strideAlignment = 0x8,
107         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
108         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
109     };
110 
111     SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
112     LOGI("request buffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
113 
114     if (buffer == nullptr) {
115         LOGE("request buffer failed: buffer is nullptr");
116         return;
117     }
118     if (buffer->GetVirAddr() == nullptr) {
119         LOGE("get virAddr failed: virAddr is nullptr");
120         return;
121     }
122 
123     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
124     LOGI("buffer width:%{public}d, height:%{public}d", buffer->GetWidth(), buffer->GetHeight());
125     DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), index);
126 
127     BufferFlushConfig flushConfig = {
128         .damage = {
129             .w = buffer->GetWidth(),
130             .h = buffer->GetHeight(),
131         },
132     };
133     ret = surface->FlushBuffer(buffer, -1, flushConfig);
134     LOGI("flushBuffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
135 }
136 
CreateSurface()137 std::shared_ptr<RSSurfaceNode> CreateSurface()
138 {
139     RSSurfaceNodeConfig config;
140     return RSSurfaceNode::Create(config);
141 }
142 }
143 
main()144 int main()
145 {
146     auto surfaceNode = CreateSurface();
147     RSDisplayNodeConfig config;
148     RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
149     int testNumber = 5;
150     for (size_t i = 0; i < testNumber; i++) {
151         int restTime = 4;
152         sleep(restTime);
153         displayNode->AddChild(surfaceNode, -1);
154         surfaceNode->SetBounds(0, 0, WIDTH, HEIGHT);
155         RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
156         DrawSurface(surfaceNode, WIDTH, HEIGHT, i);
157         sleep(restTime);
158         displayNode->RemoveChild(surfaceNode);
159         RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
160     }
161     return 0;
162 }
163