1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.. All rights reserved.
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 <cinttypes>
17 #include <codecvt>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <fstream>
21 #include <iostream>
22 #include <locale>
23 #include <memory>
24 #include <securec.h>
25 #include <sstream>
26 #include <string>
27 #include <surface.h>
28 #include <unistd.h>
29
30 #include "command/rs_base_node_command.h"
31 #include "command/rs_display_node_command.h"
32 #include "command/rs_surface_node_command.h"
33 #include "common/rs_common_def.h"
34 #include "core/transaction/rs_interfaces.h"
35 #include "core/ui/rs_display_node.h"
36 #include "core/ui/rs_surface_node.h"
37 #include "draw/canvas.h"
38 #include "draw/pen.h"
39 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_frame_ohos.h"
40 #include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_ohos.h"
41 #include "image/bitmap.h"
42 #include "pipeline/rs_render_result.h"
43 #include "pipeline/rs_render_thread.h"
44 #include "rosen_text/properties/text_style.h"
45 #include "rosen_text/properties/typography_properties.h"
46 #include "rosen_text/ui/font_collection.h"
47 #include "rosen_text/ui/typography.h"
48 #include "rosen_text/ui/typography_create.h"
49 #include "ui/rs_canvas_node.h"
50 #include "ui/rs_surface_extractor.h"
51 #include "ui/rs_ui_director.h"
52
53 using namespace std;
54 using namespace OHOS;
55 using namespace Rosen;
56 using namespace rosen;
57 using namespace Drawing;
58 using namespace Media;
59
TextToUtf16(std::string str)60 std::u16string TextToUtf16(std::string str)
61 {
62 return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(str);
63 }
64
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,size_t index)65 void DoDraw(uint8_t *addr, uint32_t width, uint32_t height, size_t index)
66 {
67 Bitmap bitmapCache;
68 BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
69 bitmapCache.Build(width, height, format);
70
71 Canvas canvas;
72 canvas.Bind(bitmapCache);
73 canvas.Clear(Drawing::Color::COLOR_WHITE);
74 TypographyStyle typoStype;
75 typoStype.textDirection_ = TextDirection::LTR;
76 typoStype.textAlign_ = TextAlign::START;
77 typoStype.maxLines_ = 1000; // maxLines 1000
78 typoStype.locale_ = "en";
79 typoStype.wordBreakType_ = WordBreakType::WordBreakTypeBreakWord;
80 std::unique_ptr<TypographyCreate> builder = TypographyCreate::CreateRosenBuilder(
81 typoStype, FontCollection::GetInstance());
82 TextStyle textStyle;
83
84 textStyle.fontFamilies_ = std::vector<std::string>(1, "Roboto");
85 textStyle.color_ = Drawing::Color::COLOR_BLACK;
86 builder->PushStyle(textStyle);
87 const std::string utf8 = "hello world!\n";
88
89 const std::u16string u16Text = TextToUtf16(utf8);
90 builder->AddText(u16Text);
91 builder->Pop();
92 // layout
93 std::unique_ptr<rosen::Typography> typography;
94 typography = builder->Build();
95 if (typography == nullptr) {
96 LOGD("typography == nullptr");
97 return;
98 }
99 double lastLayoutMaxWidth = 1000.0; // width 1000.0
100 typography->Layout(lastLayoutMaxWidth);
101 typography->Paint(&canvas, 10.0, 15.0); // pos to paint 10.0, 15.0
102 constexpr uint32_t stride = 4;
103 int32_t addrSize = width * height * stride;
104 auto ret = memcpy_s(addr, addrSize, bitmapCache.GetPixels(), addrSize);
105 if (ret != EOK) {
106 LOGD("memcpy_s failed");
107 }
108 }
109
DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t width,int32_t height,size_t index)110 void DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height, size_t index)
111 {
112 sptr<OHOS::Surface> surface = surfaceNode->GetSurface();
113 if (surface == nullptr) {
114 return;
115 }
116
117 sptr<OHOS::SurfaceBuffer> buffer;
118 int32_t releaseFence;
119 OHOS::BufferRequestConfig config = {
120 .width = width,
121 .height = height,
122 .strideAlignment = 0x8,
123 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
124 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
125 };
126
127 OHOS::SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
128 LOGD("request buffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
129
130 if (buffer == nullptr) {
131 LOGD("request buffer failed: buffer is nullptr");
132 return;
133 }
134 if (buffer->GetVirAddr() == nullptr) {
135 LOGD("get virAddr failed: virAddr is nullptr");
136 return;
137 }
138
139 auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
140 LOGD("buffer width:%{public}d, height:%{public}d", buffer->GetWidth(), buffer->GetHeight());
141
142 DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), index);
143 LOGD("DoDraw end");
144
145 OHOS::BufferFlushConfig flushConfig = {
146 .damage = {
147 .w = buffer->GetWidth(),
148 .h = buffer->GetHeight(),
149 },
150 };
151 ret = surface->FlushBuffer(buffer, -1, flushConfig);
152 LOGD("draw pointer FlushBuffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
153 }
154
CreateSurface()155 std::shared_ptr<RSSurfaceNode> CreateSurface()
156 {
157 RSSurfaceNodeConfig config;
158 return RSSurfaceNode::Create(config);
159 }
160
main(int argc,char ** argv)161 int main(int argc, char** argv)
162 {
163 auto surfaceNode = CreateSurface();
164 RSDisplayNodeConfig config;
165 RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
166 for (size_t i = 0; i < 5; i++) { // Draw 5 times
167 sleep(2); // delay 2 second
168 displayNode->AddChild(surfaceNode, -1);
169 surfaceNode->SetBounds(0, 0, 2560, 1600); // Draw Range 2560, 1600
170 RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
171 DrawSurface(surfaceNode, 2560, 1600, i); // Draw Range 2560, 1600
172 sleep(4); // delay 4 second
173 displayNode->RemoveChild(surfaceNode);
174 RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
175 }
176 return 0;
177 }
178