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