1 /*
2 * Copyright (c) 2025 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 #include <iostream>
16 #include <message_parcel.h>
17 #include <sstream>
18 #include <string>
19 #include <surface.h>
20 #include "transaction/rs_transaction.h"
21 #include "wm/window.h"
22 #include "dtk_test_base.h"
23
24 namespace OHOS {
25 namespace Rosen {
SetTestCount(int testCount)26 void TestBase::SetTestCount(int testCount)
27 {
28 testCount_ = testCount;
29 }
30
SetCanvas(TestPlaybackCanvas * canvas)31 void TestBase::SetCanvas(TestPlaybackCanvas* canvas)
32 {
33 playbackCanvas_ = canvas;
34 }
35
SetSurface(Drawing::Surface * surface)36 void TestBase::SetSurface(Drawing::Surface* surface)
37 {
38 mSurface = surface;
39 }
40
AddTestBrush(bool isAA)41 void TestBase::AddTestBrush(bool isAA)
42 {
43 Drawing::Brush brush;
44 brush.SetColor(0xFFFF0000);
45 brush.SetAntiAlias(isAA);
46 playbackCanvas_->AttachBrush(brush);
47 }
48
AddTestPen(bool isAA)49 void TestBase::AddTestPen(bool isAA)
50 {
51 Drawing::Pen pen;
52 pen.SetColor(0xFFFF0000);
53 pen.SetWidth(10.0f);
54 pen.SetAntiAlias(isAA);
55 playbackCanvas_->AttachPen(pen);
56 }
57
AddTestPen(bool isAA,float width)58 void TestBase::AddTestPen(bool isAA, float width)
59 {
60 Drawing::Pen pen;
61 pen.SetColor(0xFFFF0000);
62 pen.SetWidth(width);
63 pen.SetAntiAlias(isAA);
64 playbackCanvas_->AttachPen(pen);
65 }
66
AddTestPen(bool isAA,Drawing::Pen::JoinStyle joinStyle)67 void TestBase::AddTestPen(bool isAA, Drawing::Pen::JoinStyle joinStyle)
68 {
69 Drawing::Pen pen;
70 pen.SetColor(0xFFFF0000);
71 pen.SetWidth(10.0f);
72 pen.SetAntiAlias(isAA);
73 pen.SetJoinStyle(joinStyle);
74 playbackCanvas_->AttachPen(pen);
75 }
AddTestPen(bool isAA,Drawing::Pen::CapStyle capStyle)76 void TestBase::AddTestPen(bool isAA, Drawing::Pen::CapStyle capStyle)
77 {
78 Drawing::Pen pen;
79 pen.SetColor(0xFFFF0000);
80 pen.SetWidth(10.0f);
81 pen.SetAntiAlias(isAA);
82 pen.SetCapStyle(capStyle);
83 playbackCanvas_->AttachPen(pen);
84 }
85
AddTestPen(bool isAA,Drawing::Pen::CapStyle capStyle,Drawing::Pen::JoinStyle joinStyle)86 void TestBase::AddTestPen(bool isAA, Drawing::Pen::CapStyle capStyle, Drawing::Pen::JoinStyle joinStyle)
87 {
88 Drawing::Pen pen;
89 pen.SetColor(0xFFFF0000);
90 pen.SetWidth(10.0f);
91 pen.SetAntiAlias(isAA);
92 pen.SetCapStyle(capStyle);
93 pen.SetJoinStyle(joinStyle);
94 playbackCanvas_->AttachPen(pen);
95 }
96
AddTestBrushAndPen(bool isAA)97 void TestBase::AddTestBrushAndPen(bool isAA)
98 {
99 AddTestBrush(isAA);
100 AddTestPen(isAA);
101 }
102
ClearTestBrush()103 void TestBase::ClearTestBrush()
104 {
105 playbackCanvas_->DetachBrush();
106 }
107
ClearTestPen()108 void TestBase::ClearTestPen()
109 {
110 playbackCanvas_->DetachPen();
111 }
112
ClearTestBrushAndPen()113 void TestBase::ClearTestBrushAndPen()
114 {
115 playbackCanvas_->DetachBrush();
116 playbackCanvas_->DetachPen();
117 }
118
Recording()119 void TestBase::Recording()
120 {
121 OnRecording();
122 }
123
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)124 void TestBase::Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
125 {
126 std::cout << "rs pixelmap demo Init Rosen Backend!" << std::endl;
127 rootNode_ = RSRootNode::Create();
128 rootNode_->SetBounds(0, 0, width, height);
129 rootNode_->SetFrame(0, 0, width, height);
130 rootNode_->SetBackgroundColor(Drawing::Color::COLOR_WHITE);
131 rsUiDirector->SetRoot(rootNode_->GetId());
132 canvasNode_ = RSCanvasNode::Create();
133 canvasNode_->SetFrame(0, 0, width, height);
134 rootNode_->AddChild(canvasNode_, -1);
135 }
136
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap)137 std::shared_ptr<Drawing::Image> TestBase::OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap)
138 {
139 if (pixelmap == nullptr)
140 {
141 std::cout << "RSUIDirector::LocalCapture failed to get pixelmap, return nullptr" << std::endl;
142 return nullptr;
143 }
144 std::cout << "rs local surface demo drawImage" << std::endl;
145
146 Drawing::Bitmap bitmap;
147 auto skii = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(), SkColorType::kRGBA_8888_SkColorType,
148 SkAlphaType::kPremul_SkAlphaType);
149 auto ddgr = Drawing::ImageInfo(pixelmap->GetWidth(), pixelmap->GetHeight(), Drawing::ColorType::COLORTYPE_RGBA_8888,
150 Drawing::AlphaType::ALPHATYPE_PREMUL);
151 if (!bitmap.InstallPixels(ddgr, (void*)pixelmap->GetPixels(), skii.minRowBytes64())) {
152 std::cout << __func__ << "installPixels failed" << std::endl;
153 return nullptr;
154 }
155 auto image = bitmap.MakeImage();
156 return image;
157 }
158
MakeImage(int w,int h,MakeImageFunc func)159 std::shared_ptr<Drawing::Image> TestBase::MakeImage(int w, int h, MakeImageFunc func)
160 {
161 std::string demoName = "imagefilters";
162 RSSystemProperties::GetUniRenderEnabled();
163 sptr<WindowOption> option = new WindowOption();
164 option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
165 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
166 option->SetWindowRect({0, 0, w, h});
167 auto window = Window::Create(demoName, option);
168 window->Show();
169 usleep(30000); // sleep 30000 microsecond
170
171 auto rect = window->GetRect();
172 while (rect.width_ == 0 && rect.height_ == 0) {
173 std::cout << "rs demo create new window failed: " << rect.width_ << " " << rect.height_ << std::endl;
174 window->Hide();
175 window->Destroy();
176 window = Window::Create(demoName, option);
177 window->Show();
178 usleep(30000); // sleep 30000 microsecond
179 rect = window->GetRect();
180 }
181 std::cout << "rs demo create new window success: " << rect.width_ << " " << rect.height_ << std::endl;
182 auto surfaceNode = window->GetSurfaceNode();
183
184 auto rsUiDirector = RSUIDirector::Create();
185 rsUiDirector->Init();
186 RSTransaction::FlushImplicitTransaction();
187
188 rsUiDirector->SetRSSurfaceNode(surfaceNode);
189 Init(rsUiDirector, rect.width_, rect.height_);
190 rsUiDirector->SendMessages();
191
192 auto canvas = canvasNode_->BeginRecording(rect.width_, rect.height_);
193 auto newCanvas = (TestPlaybackCanvas*)(canvas);
194
195 // core code;
196 func(newCanvas, w, h);
197
198 canvasNode_->FinishRecording();
199 rsUiDirector->SendMessages();
200 usleep(16666); // sleep 16666 microsecond
201 usleep(50000); // sleep 50000 microsecond
202 auto newImage = OnSurfaceCapture(window->Snapshot());
203 window->Hide();
204 window->Destroy();
205 return newImage;
206 }
207
GetEffectTestImage(const std::string & pathName)208 std::shared_ptr<Drawing::Image> TestBase::GetEffectTestImage(const std::string& pathName)
209 {
210 if (auto iter = effectTestImageMap_.find(pathName);
211 iter != effectTestImageMap_.end()) {
212 return iter->second;
213 }
214 auto image = std::make_shared<Drawing::Image>();
215 auto encodeDate = Drawing::Data::MakeFromFileName(pathName.c_str());
216 image->MakeFromEncoded(encodeDate);
217 effectTestImageMap_[pathName] = image;
218 return image;
219 }
220
GetNewColorSpaceSurface()221 std::shared_ptr<Drawing::Surface> TestBase::GetNewColorSpaceSurface()
222 {
223 if (csSurface_) {
224 return csSurface_;
225 }
226 auto colorspace = Drawing::ColorSpace::CreateRGB(Drawing::CMSTransferFuncType::DOT2,
227 Drawing::CMSMatrixType::ADOBE_RGB);
228 // 1000 is the width of the panda1000 picture which we used
229 Drawing::ImageInfo imageInfo(1000, 1000, Drawing::ColorType::COLORTYPE_RGBA_8888,
230 Drawing::AlphaType::ALPHATYPE_PREMUL, colorspace);
231 auto context = playbackCanvas_->GetGPUContext();
232 csSurface_ = Drawing::Surface::MakeRenderTarget(context.get(), false, imageInfo);
233 return csSurface_;
234 }
235
GetTestRuntimeEffectForShader(const char * glsl)236 std::shared_ptr<Drawing::RuntimeEffect> TestBase::GetTestRuntimeEffectForShader(const char* glsl)
237 {
238 std::hash<std::string> hasher;
239 size_t hash = hasher(glsl);
240 if (auto iter = runtimeEffectMap_.find(hash);
241 iter != runtimeEffectMap_.end()) {
242 return iter->second;
243 }
244 std::shared_ptr<Drawing::RuntimeEffect> runtimeEffect =
245 Drawing::RuntimeEffect::CreateForShader(glsl);
246 if (runtimeEffect) {
247 runtimeEffectMap_[hash] = runtimeEffect;
248 }
249 return runtimeEffect;
250 }
251
GetTestRuntimeEffectForBlender(const char * glsl)252 std::shared_ptr<Drawing::RuntimeEffect> TestBase::GetTestRuntimeEffectForBlender(const char* glsl)
253 {
254 std::hash<std::string> hasher;
255 size_t hash = hasher(glsl);
256 if (auto iter = runtimeEffectMap_.find(hash);
257 iter != runtimeEffectMap_.end()) {
258 return iter->second;
259 }
260 std::shared_ptr<Drawing::RuntimeEffect> runtimeEffect =
261 Drawing::RuntimeEffect::CreateForBlender(glsl);
262 if (runtimeEffect) {
263 runtimeEffectMap_[hash] = runtimeEffect;
264 }
265 return runtimeEffect;
266 }
267
ClipPath(bool doAntiAlias)268 void TestBase::ClipPath(bool doAntiAlias)
269 {
270 Drawing::Path path;
271 path.AddRect({ 200, 300, 700, 800 }); // rect region (200, 300, 700, 800)
272 path.SetFillStyle(Drawing::PathFillType::INVERSE_WINDING);
273 playbackCanvas_->Save();
274 playbackCanvas_->ClipPath(path, Drawing::ClipOp::DIFFERENCE, doAntiAlias);
275 playbackCanvas_->Clear(Drawing::Color::COLOR_GREEN);
276 playbackCanvas_->Restore();
277 }
278
ClipRect(bool doAntiAlias)279 void TestBase::ClipRect(bool doAntiAlias)
280 {
281 auto rect = Drawing::Rect(100, 100, 200, 200); // rect region (100, 100, 200, 200)
282 playbackCanvas_->Save();
283 playbackCanvas_->ClipRect(rect, Drawing::ClipOp::DIFFERENCE, doAntiAlias);
284 playbackCanvas_->Clear(Drawing::Color::COLOR_RED);
285 playbackCanvas_->Restore();
286 }
287
ClipRoundRectG2(bool doAntiAlias)288 void TestBase::ClipRoundRectG2(bool doAntiAlias)
289 {
290 auto rect = Drawing::Rect(100, 100, 250, 250); // rect region (100, 100, 250, 250)
291 auto rrect = Drawing::RoundRect(rect, 30.0f, 30.0f); // 30.0f is angle
292 playbackCanvas_->Save();
293 playbackCanvas_->ClipRoundRect(rrect, Drawing::ClipOp::DIFFERENCE, doAntiAlias);
294 playbackCanvas_->Clear(Drawing::Color::COLOR_RED);
295 playbackCanvas_->Restore();
296 }
297
ClipRoundRectG2capsule(bool doAntiAlias)298 void TestBase::ClipRoundRectG2capsule(bool doAntiAlias)
299 {
300 auto rect = Drawing::Rect(100, 100, 250, 200); // rect region (100, 100, 250, 200)
301 auto rrect = Drawing::RoundRect(rect, 50.0f, 50.0f); // 50.0f is angle
302 playbackCanvas_->Save();
303 playbackCanvas_->ClipRoundRect(rrect, Drawing::ClipOp::DIFFERENCE, doAntiAlias);
304 playbackCanvas_->Clear(Drawing::Color::COLOR_RED);
305 playbackCanvas_->Restore();
306 }
307
ClipRoundRectnotG2(bool doAntiAlias)308 void TestBase::ClipRoundRectnotG2(bool doAntiAlias)
309 {
310 auto rect = Drawing::Rect(100, 100, 200, 200); // rect region (100, 100, 200, 200)
311 auto rrect = Drawing::RoundRect(rect, 30.0f, 30.0f); // 30.0f is angle
312 playbackCanvas_->Save();
313 playbackCanvas_->ClipRoundRect(rrect, Drawing::ClipOp::DIFFERENCE, doAntiAlias);
314 playbackCanvas_->Clear(Drawing::Color::COLOR_RED);
315 playbackCanvas_->Restore();
316 }
317
318 } // namespace Rosen
319 } // namespace OHOS