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 <iostream>
17
18 #include "dm/display_manager.h"
19 #include "securec.h"
20
21 #include "draw/canvas.h"
22 #include "image/bitmap.h"
23
24 #include "transaction/rs_transaction.h"
25 #include "ui/rs_surface_node.h"
26 #include "transaction/rs_interfaces.h"
27
28 using namespace OHOS;
29 using namespace OHOS::Rosen;
30
31 constexpr uint32_t SLEEP_TIME = 3;
32 constexpr uint32_t POINTER_WIDTH = 100;
33 constexpr uint32_t POINTER_HEIGHT = 200;
34 constexpr uint32_t POINTER_WINDOW_INIT_SIZE = 64;
35 std::shared_ptr<RSSurfaceNode> surfaceNode;
36 uint64_t screenId = 0;
37
38 namespace {
Resize(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t width,int32_t height)39 void Resize(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height)
40 {
41 width = (width / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
42 height = (height / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
43 surfaceNode->SetBoundsWidth(width);
44 surfaceNode->SetBoundsHeight(height);
45 }
46
MoveTo(std::shared_ptr<RSSurfaceNode> surfaceNode,int32_t x,int32_t y)47 void MoveTo(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t x, int32_t y)
48 {
49 surfaceNode->SetBounds(
50 x, y, surfaceNode->GetStagingProperties().GetBounds().z_, surfaceNode->GetStagingProperties().GetBounds().w_);
51 }
52
GetSurfaceBuffer(sptr<Surface> ohosSurface,int32_t width,int32_t height)53 sptr<SurfaceBuffer> GetSurfaceBuffer(sptr<Surface> ohosSurface, int32_t width, int32_t height)
54 {
55 sptr<SurfaceBuffer> buffer;
56 int32_t releaseFence = 0;
57 BufferRequestConfig config = {
58 .width = width,
59 .height = height,
60 .strideAlignment = 0x8,
61 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
62 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
63 };
64
65 SurfaceError ret = ohosSurface->RequestBuffer(buffer, releaseFence, config);
66 if (ret != SURFACE_ERROR_OK) {
67 return nullptr;
68 }
69 return buffer;
70 }
71
DoDraw(uint8_t * addr,uint32_t width,uint32_t height)72 void DoDraw(uint8_t* addr, uint32_t width, uint32_t height)
73 {
74 Drawing::Bitmap bitmap;
75 Drawing::BitmapFormat format { Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_OPAQUE };
76 bitmap.Build(width, height, format);
77
78 Drawing::Canvas canvas;
79 canvas.Bind(bitmap);
80 canvas.Clear(Drawing::Color::COLOR_GREEN);
81 Drawing::Pen pen;
82 pen.SetAntiAlias(true);
83 pen.SetColor(Drawing::Color::COLOR_RED);
84 Drawing::scalar penWidth = 1;
85 pen.SetWidth(penWidth);
86 canvas.AttachPen(pen);
87 Drawing::Point startPt(10, 10);
88 Drawing::Point endPt(50, 50);
89 canvas.DrawLine(startPt, endPt);
90 static constexpr uint32_t stride = 4;
91 uint32_t addrSize = width * height * stride;
92 memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
93 }
94
InitSurfaceStyle(std::shared_ptr<RSSurfaceNode> surfaceNode)95 void InitSurfaceStyle(std::shared_ptr<RSSurfaceNode> surfaceNode)
96 {
97 auto ohosSurface = surfaceNode->GetSurface();
98 if (ohosSurface == nullptr) {
99 return;
100 }
101 sptr<SurfaceBuffer> buffer = GetSurfaceBuffer(ohosSurface, surfaceNode->GetStagingProperties().GetBounds().z_,
102 surfaceNode->GetStagingProperties().GetBounds().w_);
103 if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
104 return;
105 }
106 auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
107 DoDraw(addr, buffer->GetWidth(), buffer->GetHeight());
108 BufferFlushConfig flushConfig = {
109 .damage = {
110 .w = buffer->GetWidth(),
111 .h = buffer->GetHeight(),
112 }
113 };
114 ohosSurface->FlushBuffer(buffer, -1, flushConfig);
115 }
116
InitSurface()117 bool InitSurface()
118 {
119 std::cout << "InitSurface" << std::endl;
120 DisplayId displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
121 RSSurfaceNodeConfig surfaceNodeConfig;
122 surfaceNodeConfig.SurfaceNodeName = "pointer window";
123 RSSurfaceNodeType surfaceNodeType = RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
124 std::cout << "RSSurfaceNode::Create" <<std::endl;
125 surfaceNode = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
126
127 if (!surfaceNode) {
128 return false;
129 }
130
131 std::cout << "SetFrameGravity" <<std::endl;
132 surfaceNode->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
133 surfaceNode->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
134 int width = (POINTER_WIDTH / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
135 int height = (POINTER_HEIGHT / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
136 surfaceNode->SetBounds(100, 300, width, height);
137 surfaceNode->SetBackgroundColor(SK_ColorGREEN);
138
139 // Attach RSSurfaceNode to RSDisplayNode through dms
140 // DisplayManager::GetInstance().AddSurfaceNodeToDisplay(displayId, surfaceNode);
141
142 // Attach RSSurfaceNode to RSDisplayNode through the AttachToDisplay interface of RSSurfaceNode
143 std::cout << "GetDisplayById: " << std::endl;
144 screenId = DisplayManager::GetInstance().GetDisplayById(displayId)->GetId();
145 std::cout << "ScreenId: " << screenId << std::endl;
146 surfaceNode->AttachToDisplay(screenId);
147
148 std::cout << "RSTranscation::FlushImplicitTransaction" << std::endl;
149 RSTransaction::FlushImplicitTransaction();
150 sleep(SLEEP_TIME);
151 return true;
152 }
153
154 bool isRemote = true;
155
PrintCallback()156 void PrintCallback()
157 {
158 std::cout << "OnRemoteDied Callback" << std::endl;
159 isRemote = false;
160 }
161 }
162
main()163 int main()
164 {
165 OnRemoteDiedCallback callback = PrintCallback;
166 RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
167
168 std::cout << "rs pointer window demo start!" << std::endl;
169 std::cout << "rs pointer window demo stage 1 Init" << std::endl;
170 InitSurface();
171
172 // Attach and Detach
173 std::cout << "rs pointer window demo stage 2 Detach" << std::endl;
174 surfaceNode->DetachToDisplay(screenId);
175 RSTransaction::FlushImplicitTransaction();
176 sleep(SLEEP_TIME);
177 std::cout << "rs pointer window demo stage 2 Attach" << std::endl;
178 surfaceNode->AttachToDisplay(screenId);
179 RSTransaction::FlushImplicitTransaction();
180 sleep(SLEEP_TIME);
181
182 // Resize
183 std::cout << "rs pointer window demo stage 3 Resize" << std::endl;
184 Resize(surfaceNode, POINTER_WIDTH / 2, POINTER_HEIGHT / 2);
185 RSTransaction::FlushImplicitTransaction();
186 sleep(SLEEP_TIME);
187
188 // SetStyle
189 std::cout << "rs pointer window demo stage 4 SetStyle" << std::endl;
190 InitSurfaceStyle(surfaceNode);
191 RSTransaction::FlushImplicitTransaction();
192 sleep(SLEEP_TIME);
193
194 // Hide
195 std::cout << "rs pointer window demo stage 5 Hide" << std::endl;
196 surfaceNode->SetVisible(false);
197 RSTransaction::FlushImplicitTransaction();
198 sleep(SLEEP_TIME);
199 // Show
200 std::cout << "rs pointer window demo stage 6 Show" << std::endl;
201 surfaceNode->SetVisible(true);
202 RSTransaction::FlushImplicitTransaction();
203 sleep(SLEEP_TIME);
204
205 std::cout << "rs pointer window demo stage MoveTo" << std::endl;
206 while (isRemote) {
207 // while (true) {
208 // MoveTo
209 MoveTo(surfaceNode, 0, 0);
210 RSTransaction::FlushImplicitTransaction();
211 sleep(SLEEP_TIME);
212 MoveTo(surfaceNode, 100, 160);
213 RSTransaction::FlushImplicitTransaction();
214 sleep(SLEEP_TIME);
215 MoveTo(surfaceNode, 320, 640);
216 RSTransaction::FlushImplicitTransaction();
217 sleep(SLEEP_TIME);
218 while (!isRemote) {
219 std::cout << "ReInitSurface" << std::endl;
220 isRemote = InitSurface();
221 }
222 }
223
224 std::cout << "rs pointer window demo end!" << std::endl;
225 return 0;
226 }