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::CURSOR_NODE;
124 std::cout << "RSSurfaceNode::Create" <<std::endl;
125 surfaceNode = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
126 if (!surfaceNode) {
127 return false;
128 }
129
130 std::cout << "SetFrameGravity" <<std::endl;
131 surfaceNode->SetFrameGravity(Gravity::RESIZE_ASPECT_FILL);
132 surfaceNode->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
133 int width = (POINTER_WIDTH / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
134 int height = (POINTER_HEIGHT / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
135 surfaceNode->SetBounds(100, 300, width, height);
136 surfaceNode->SetBackgroundColor(SK_ColorGREEN);
137
138 // Attach RSSurfaceNode to RSDisplayNode through dms
139 // DisplayManager::GetInstance().AddSurfaceNodeToDisplay(displayId, surfaceNode);
140
141 // Attach RSSurfaceNode to RSDisplayNode through the AttachToDisplay interface of RSSurfaceNode
142 std::cout << "GetDisplayById: " << std::endl;
143 screenId = DisplayManager::GetInstance().GetDisplayById(displayId)->GetId();
144 std::cout << "ScreenId: " << screenId << std::endl;
145 surfaceNode->AttachToDisplay(screenId);
146
147 std::cout << "RSTranscation::FlushImplicitTransaction" << std::endl;
148 RSTransaction::FlushImplicitTransaction();
149 sleep(SLEEP_TIME);
150 return true;
151 }
152
153 bool isRemote = true;
154
PrintCallback()155 void PrintCallback()
156 {
157 std::cout << "OnRemoteDied Callback" << std::endl;
158 isRemote = false;
159 }
160 }
161
main()162 int main()
163 {
164 OnRemoteDiedCallback callback = PrintCallback;
165 RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
166
167 std::cout << "rs pointer window demo start!" << std::endl;
168 std::cout << "rs pointer window demo stage 1 Init" << std::endl;
169 InitSurface();
170
171 // Attach and Detach
172 std::cout << "rs pointer window demo stage 2 Detach" << std::endl;
173 surfaceNode->DetachToDisplay(screenId);
174 RSTransaction::FlushImplicitTransaction();
175 sleep(SLEEP_TIME);
176 std::cout << "rs pointer window demo stage 2 Attach" << std::endl;
177 surfaceNode->AttachToDisplay(screenId);
178 RSTransaction::FlushImplicitTransaction();
179 sleep(SLEEP_TIME);
180
181 // Resize
182 std::cout << "rs pointer window demo stage 3 Resize" << std::endl;
183 Resize(surfaceNode, POINTER_WIDTH / 2, POINTER_HEIGHT / 2);
184 RSTransaction::FlushImplicitTransaction();
185 sleep(SLEEP_TIME);
186
187 // SetStyle
188 std::cout << "rs pointer window demo stage 4 SetStyle" << std::endl;
189 InitSurfaceStyle(surfaceNode);
190 RSTransaction::FlushImplicitTransaction();
191 sleep(SLEEP_TIME);
192
193 // Hide
194 std::cout << "rs pointer window demo stage 5 Hide" << std::endl;
195 surfaceNode->SetVisible(false);
196 RSTransaction::FlushImplicitTransaction();
197 sleep(SLEEP_TIME);
198 // Show
199 std::cout << "rs pointer window demo stage 6 Show" << std::endl;
200 surfaceNode->SetVisible(true);
201 RSTransaction::FlushImplicitTransaction();
202 sleep(SLEEP_TIME);
203
204 std::cout << "rs pointer window demo stage MoveTo" << std::endl;
205 while (isRemote) {
206 // MoveTo
207 MoveTo(surfaceNode, 0, 0);
208 RSTransaction::FlushImplicitTransaction();
209 sleep(SLEEP_TIME);
210 MoveTo(surfaceNode, 100, 160);
211 RSTransaction::FlushImplicitTransaction();
212 sleep(SLEEP_TIME);
213 MoveTo(surfaceNode, 320, 640);
214 RSTransaction::FlushImplicitTransaction();
215 sleep(SLEEP_TIME);
216 while (!isRemote) {
217 std::cout << "ReInitSurface" << std::endl;
218 isRemote = InitSurface();
219 }
220 }
221
222 std::cout << "rs pointer window demo end!" << std::endl;
223 return 0;
224 }