1 /*
2 * Copyright (c) 2022 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
19 #include "command/rs_base_node_command.h"
20 #include "command/rs_display_node_command.h"
21 #include "command/rs_surface_node_command.h"
22 #include "common/rs_common_def.h"
23
24 #include "pipeline/rs_render_result.h"
25 #include "pipeline/rs_render_thread.h"
26 #include "transaction/rs_interfaces.h"
27 #include "ui/rs_canvas_node.h"
28 #include "ui/rs_surface_extractor.h"
29 #include "ui/rs_ui_director.h"
30 #include "ui/rs_display_node.h"
31 #include "ui/rs_surface_node.h"
32 #include "render_context/render_context.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 using namespace OHOS;
38 using namespace OHOS::Rosen;
39 using namespace std;
40
41 namespace OHOS::Rosen {
42 #ifdef RS_ENABLE_GPU
43 RenderContext* rc_ = nullptr;
44 #endif
45 constexpr int SURFACE_NODE_SIZE = 100;
46
47 namespace pipelineTestUtils {
48 constexpr bool wrongExit = false;
49 constexpr bool successExit = false;
50
51 class ToDrawSurface {
52 public:
53 using drawFun = std::function<void(Drawing::Canvas&, Drawing::Brush&)>;
ToDrawSurface()54 ToDrawSurface()
55 {
56 // Do not hold it. Use it As ToDrawSurface::Sample().
57 };
58
SetSurfaceNode(const std::shared_ptr<RSSurfaceNode> surfaceNode)59 inline ToDrawSurface& SetSurfaceNode(const std::shared_ptr<RSSurfaceNode> surfaceNode)
60 {
61 surfaceNode_ = surfaceNode;
62 return *this;
63 }
64
SetSurfaceNodeSize(Drawing::Rect surfaceGeometry)65 inline ToDrawSurface& SetSurfaceNodeSize(Drawing::Rect surfaceGeometry)
66 {
67 surfaceGeometry_ = surfaceGeometry;
68 return *this;
69 }
70
SetBufferSize(int width,int height)71 inline ToDrawSurface& SetBufferSize(int width, int height)
72 {
73 bufferSize_ = Drawing::Rect(0, 0, width, height);
74 return *this;
75 }
76
SetBufferSizeAuto()77 inline ToDrawSurface& SetBufferSizeAuto()
78 {
79 bufferSize_ = surfaceGeometry_;
80 return *this;
81 }
82
SetBufferSize(Drawing::Rect bufferSize)83 inline ToDrawSurface& SetBufferSize(Drawing::Rect bufferSize)
84 {
85 // bufferSize has no XY
86 bufferSize_ = bufferSize;
87 return *this;
88 }
89
SetShapeColor(uint32_t color)90 inline ToDrawSurface& SetShapeColor(uint32_t color)
91 {
92 color_ = color;
93 return *this;
94 }
95
SetDraw(drawFun drawShape)96 inline ToDrawSurface& SetDraw(drawFun drawShape)
97 {
98 drawShape_ = drawShape;
99 return *this;
100 }
101
Run()102 bool Run()
103 {
104 if (surfaceNode_ == nullptr) {
105 return false;
106 }
107 auto x = surfaceGeometry_.GetLeft();
108 auto y = surfaceGeometry_.GetTop();
109 auto width = surfaceGeometry_.GetWidth();
110 auto height = surfaceGeometry_.GetHeight();
111 surfaceNode_->SetBounds(x, y, width, height);
112 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_);
113 if (rsSurface == nullptr) {
114 return wrongExit;
115 }
116 #ifdef RS_ENABLE_GPU
117 // SetRenderContext must before rsSurface->RequestFrame, or it will failed.
118 if (rc_) {
119 rsSurface->SetRenderContext(rc_);
120 } else {
121 cout << "DrawSurface: RenderContext is nullptr\n";
122 }
123 #endif
124 auto framePtr = rsSurface->RequestFrame(bufferSize_.GetWidth(), bufferSize_.GetHeight());
125 if (!framePtr) {
126 // SetRenderContext must before rsSurface->RequestFrame,
127 // or frameptr will be nullptr.
128 cout << "DrawSurface: frameptr is nullptr\n";
129 return wrongExit;
130 }
131 auto canvas = framePtr->GetCanvas();
132 if (!canvas) {
133 cout << "DrawSurface: canvas is nullptr\n";
134 return wrongExit;
135 }
136 canvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
137 Drawing::Brush brush;
138 brush.SetAntiAlias(true);
139 brush.SetColor(color_);
140 if (!drawShape_) {
141 cout << "DrawSurface: drawShape_ is nullptr\n";
142 return wrongExit;
143 }
144 drawShape_(*(canvas), brush);
145 framePtr->SetDamageRegion(0, 0, surfaceGeometry_.GetWidth(), surfaceGeometry_.GetHeight());
146 rsSurface->FlushFrame(framePtr);
147 return successExit;
148 }
149 private:
150 Drawing::Rect surfaceGeometry_ = {0.f, 0.f, 0.f, 0.f};
151 Drawing::Rect bufferSize_ = {0.f, 0.f, 0.f, 0.f};
152 drawFun drawShape_;
153 uint32_t color_ = 0;
154 std::shared_ptr<RSSurfaceNode> surfaceNode_ = nullptr;
155 }; // class ToDrawSurface
156
CreateSurface(int surfaceNodeX,int surfaceNodeY,int surfaceNodeWidth,int surfaceNodeHeight,uint32_t shapeColor)157 static std::shared_ptr<RSSurfaceNode> CreateSurface(int surfaceNodeX, int surfaceNodeY,
158 int surfaceNodeWidth, int surfaceNodeHeight, uint32_t shapeColor)
159 {
160 RSSurfaceNodeConfig config;
161 auto surfaceNode = RSSurfaceNode::Create(config);
162
163 ToDrawSurface()
164 .SetSurfaceNode(surfaceNode)
165 .SetShapeColor(shapeColor)
166 .SetSurfaceNodeSize(Drawing::Rect(surfaceNodeX, surfaceNodeY,
167 surfaceNodeWidth + surfaceNodeX, surfaceNodeHeight + surfaceNodeY))
168 .SetBufferSizeAuto()
169 .SetDraw([&](Drawing::Canvas &canvas, Drawing::Brush &brush) -> void {
170 canvas.AttachBrush(brush);
171 canvas.DrawRect(Drawing::Rect(0, 0, surfaceNodeWidth, surfaceNodeHeight));
172 canvas.DetachBrush();
173 })
174 .Run();
175
176 return surfaceNode;
177 }
178
CreateDisplayNode(std::shared_ptr<RSSurfaceNode> surfaceNode)179 static std::shared_ptr<RSDisplayNode> CreateDisplayNode(std::shared_ptr<RSSurfaceNode> surfaceNode)
180 {
181 RSDisplayNodeConfig displayConfig;
182 RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(displayConfig);
183 displayNode->AddChild(surfaceNode, -1);
184 return displayNode;
185 }
186 } // namespace pipelineTestUtils
187
188 // This test case is designed for temporary result demonstration.
189 // It could be removed after DMS implements this feature.
190 class RSDisplayModeTestCase {
191 public:
GetInstance()192 inline static RSDisplayModeTestCase& GetInstance()
193 {
194 static RSDisplayModeTestCase c;
195 return c;
196 }
197
GetOrSetDisplayMode(RSDisplayNode::SharedPtr targetDisplayNode,RSDisplayNode::SharedPtr sourceDisplayNode)198 void GetOrSetDisplayMode(RSDisplayNode::SharedPtr targetDisplayNode, RSDisplayNode::SharedPtr sourceDisplayNode)
199 {
200 auto transactionProxy = RSTransactionProxy::GetInstance();
201 while (true) {
202 int testType = -1;
203 int param = -1;
204
205 cout << " ---------------------loop start------------------------" << endl;
206 cout << "Input test type, 1: Get, 0: Set:, Others: End Test " << endl;
207 cin >> testType;
208 if (testType != 1 && testType != 0) {
209 return;
210 }
211 if (testType == 0) {
212 cout << "Input param, 1: is mirror, 0: not mirror: " << endl;
213 cin >> param;
214 }
215 cout << " " << endl;
216
217 if (testType == 1) {
218 auto isMirrorDisplay = targetDisplayNode->IsMirrorDisplay() ? "is mirror" : "not mirror";
219 cout << "Get display mode result: "<< isMirrorDisplay << endl;
220 } else if (testType == 0) {
221 bool isMirrored = param == 1 ? true : false;
222 RSDisplayNodeConfig config = {0, isMirrored, sourceDisplayNode->GetId()};
223 cout << "Set display mode "<< isMirrored << " , source node id " << config.mirrorNodeId << endl;
224 targetDisplayNode->SetDisplayNodeMirrorConfig(config);
225 }
226
227 if (transactionProxy != nullptr) {
228 transactionProxy->FlushImplicitTransaction();
229 }
230 }
231 return;
232 }
233
InitTestCase()234 void InitTestCase()
235 {
236 ScreenId id = RSInterfaces::GetInstance().GetDefaultScreenId();
237 auto activeModeInfo = RSInterfaces::GetInstance().GetScreenActiveMode(id);
238
239 screenWidth_ = activeModeInfo.GetScreenWidth();
240 screenHeight_ = activeModeInfo.GetScreenHeight();
241 std::cout << "Display " << id << " active mode info:\n";
242 std::cout << "Width: " << screenWidth_ << ", Height: " << screenHeight_;
243
244 RenderContextInit();
245 }
246
TestCaseDefault()247 void TestCaseDefault()
248 {
249 auto sourceSurcaseNode = pipelineTestUtils::CreateSurface(SURFACE_NODE_SIZE, screenHeight_ * 0.2f,
250 screenWidth_ * 0.4f, screenHeight_ * 0.3f, 0xff0000ff);
251 auto sourceDisplayNode = pipelineTestUtils::CreateDisplayNode(sourceSurcaseNode);
252 auto targetSurfaceNode = pipelineTestUtils::CreateSurface(SURFACE_NODE_SIZE, screenHeight_ * 0.6f,
253 screenWidth_ * 0.6f, screenHeight_ * 0.3f, 0xffff0000);
254 auto targetDisplayNode = pipelineTestUtils::CreateDisplayNode(targetSurfaceNode);
255
256 auto transactionProxy = RSTransactionProxy::GetInstance();
257 if (transactionProxy != nullptr) {
258 transactionProxy->FlushImplicitTransaction();
259 }
260
261 GetOrSetDisplayMode(targetDisplayNode, sourceDisplayNode);
262
263 sourceDisplayNode->RemoveFromTree();
264 targetDisplayNode->RemoveFromTree();
265
266 if (transactionProxy != nullptr) {
267 transactionProxy->FlushImplicitTransaction();
268 }
269 }
270 private:
271 RSDisplayModeTestCase() = default;
RenderContextInit()272 void RenderContextInit()
273 {
274 #ifdef RS_ENABLE_GPU
275 cout << "RS_ENABLE_GPU is true. \n";
276 cout << "Init RenderContext start. \n";
277 rc_ = RenderContextFactory::GetInstance().CreateEngine();
278 if (rc_) {
279 cout << "Init RenderContext success.\n";
280 rc_->InitializeEglContext();
281 } else {
282 cout << "Init RenderContext failed, RenderContext is nullptr.\n";
283 }
284 cout << "Init RenderContext start.\n";
285 #endif
286 }
287 int screenWidth_ = 0;
288 int screenHeight_ = 0;
289 }; // class RSDisplayModeTestCase
290 } // namespace OHOS::Rosen
291
main()292 int main()
293 {
294 RSDisplayModeTestCase::GetInstance().InitTestCase();
295 RSDisplayModeTestCase::GetInstance().TestCaseDefault();
296 return 0;
297 }
298