• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <random>
18 #include <string>
19 
20 #include "include/core/SkColor.h"
21 #include "include/core/SkTextBlob.h"
22 #include "refbase.h"
23 #include "render_context/render_context.h"
24 #include "transaction/rs_transaction.h"
25 #include "ui/rs_surface_extractor.h"
26 #include "ui/rs_surface_node.h"
27 #include "wm/window.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 namespace Test {
32 constexpr int DEFAULT_DISPLAY_ID = 0;
33 constexpr int WINDOW_LEFT = 100;
34 constexpr int WINDOW_TOP = 200;
35 constexpr int WINDOW_WIDTH = 360;
36 constexpr int WINDOW_HEIGHT = 360;
37 constexpr int BUFFER_WIDTH = 360;
38 constexpr int BUFFER_HEIGHT = 360;
39 constexpr float MIN_SCALE = 0.5f;
40 constexpr float MAX_SCALE = 2.0f;
41 
GetRandomScale()42 float GetRandomScale()
43 {
44     static std::random_device seed;
45     std::mt19937_64 gen(seed());
46     std::uniform_real_distribution<> distribution(MIN_SCALE, MAX_SCALE);
47     return distribution(gen);
48 }
49 
50 // we can make this demo and run it on the device,
51 // to visualize the surface's scale effects.
52 class RsSurfaceNodeScaleTestDemo {
53 public:
RsSurfaceNodeScaleTestDemo()54     RsSurfaceNodeScaleTestDemo()
55     {
56 #ifdef ACE_ENABLE_GPU
57         renderContext_ = std::make_unique<RenderContext>();
58         renderContext_->InitializeEglContext();
59 #endif // ACE_ENABLE_GPU
60 
61         sptr<WindowOption> option(new WindowOption());
62         option->SetDisplayId(DEFAULT_DISPLAY_ID);
63         option->SetWindowRect( {WINDOW_LEFT, WINDOW_TOP, WINDOW_WIDTH, WINDOW_HEIGHT} );
64         option->SetWindowType(WindowType::APP_MAIN_WINDOW_BASE);
65         option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
66         option->SetWindowName("scale_demo");
67         window_ = Window::Create(option->GetWindowName(), option);
68         if (window_ != nullptr) {
69             surfaceNode_ = window_->GetSurfaceNode();
70             // surface bounds is window rect.
71             surfaceNode_->SetBounds(WINDOW_LEFT, WINDOW_TOP, WINDOW_WIDTH, WINDOW_HEIGHT);
72             RSTransaction::FlushImplicitTransaction();
73             window_->Show();
74         } else {
75             std::cout << "Failed to create window!" << std::endl;
76         }
77     }
78 
~RsSurfaceNodeScaleTestDemo()79     ~RsSurfaceNodeScaleTestDemo() noexcept
80     {
81         if (window_ != nullptr) {
82             window_->Hide();
83             window_->Destroy();
84         }
85     }
86 
Run()87     void Run()
88     {
89         if (surfaceNode_ == nullptr) {
90             return;
91         }
92 
93         auto rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode_);
94         if (rsSurface == nullptr) {
95             return;
96         }
97 
98 #ifdef ACE_ENABLE_GPU
99         if (renderContext_ != nullptr) {
100             rsSurface->SetRenderContext(renderContext_.get());
101         }
102 #endif // ACE_ENABLE_GPU
103 
104         // test 50 frames.
105         for (int i = 0; i < 50; ++i) {
106             // get random scales and set them with pivot(start point or center point).
107             float scaleX = GetRandomScale();
108             float scaleY = GetRandomScale();
109             surfaceNode_->SetScale(scaleX, scaleY);
110             // default pivot: center
111             float pivotX = 0.5f; // centerX: 0.5
112             float pivotY = 0.5f; // centerY: 0.5
113             std::string pivotInfo = "Pivot: centor(0.5, 0.5)";
114             // make pivot to start point if (i % 2 == 0)
115             if (i % 2 == 0) {
116                 pivotX = 0.0f;
117                 pivotY = 0.0f;
118                 pivotInfo = "Pivot: start(0, 0)";
119             }
120             surfaceNode_->SetPivot(pivotX, pivotY);
121             RSTransaction::FlushImplicitTransaction();
122 
123             auto frame = rsSurface->RequestFrame(BUFFER_WIDTH, BUFFER_HEIGHT);
124             if (frame == nullptr) {
125                 std::cout << "Failed to create frame!" << std::endl;
126                 return;
127             }
128             auto canvas = frame->GetCanvas();
129             if (canvas == nullptr) {
130                 std::cout << "Failed to create canvas!" << std::endl;
131                 return;
132             }
133             canvas->clear(SK_ColorWHITE);
134             SkPaint paint;
135             paint.setAntiAlias(true);
136             paint.setStyle(SkPaint::kFill_Style);
137             paint.setStrokeWidth(20); // line width: 20
138             paint.setStrokeJoin(SkPaint::kRound_Join);
139             paint.setColor(SK_ColorBLUE);
140             std::string scaleInfo;
141             scaleInfo += ("ScaleX: " + std::to_string(scaleX) + "\n");
142             scaleInfo += ("ScaleY: " + std::to_string(scaleY) + "\n");
143             sk_sp<SkTextBlob> scaleInfoTextBlob = SkTextBlob::MakeFromString(
144                 scaleInfo.c_str(), SkFont(nullptr, 16.0f, 1.0f, 0.0f)); // font size: 16
145             canvas->drawTextBlob(scaleInfoTextBlob.get(), 20, 50, paint); // start point is (20, 50)
146             sk_sp<SkTextBlob> pivotInfoTextBlob = SkTextBlob::MakeFromString(
147                 pivotInfo.c_str(), SkFont(nullptr, 16.0f, 1.0f, 0.0f)); // font size: 16
148             canvas->drawTextBlob(pivotInfoTextBlob.get(), 20, 100, paint); // start point is (20, 100)
149             frame->SetDamageRegion(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT);
150             rsSurface->FlushFrame(frame);
151 
152             sleep(2); // sleep 2s
153         }
154     }
155 
156 private:
157 #ifdef ACE_ENABLE_GPU
158     std::unique_ptr<RenderContext> renderContext_;
159 #endif // ACE_ENABLE_GPU
160 
161     sptr<Window> window_;
162     std::shared_ptr<RSSurfaceNode> surfaceNode_;
163 };
164 } // namespace Test
165 } // namespace Rosen
166 } // namespace OHOS
167 
main()168 int main()
169 {
170     std::cout << "rs surface node scale demo start!" << std::endl;
171     OHOS::Rosen::Test::RsSurfaceNodeScaleTestDemo demo;
172     demo.Run();
173     std::cout << "rs surface node scale demo end!" << std::endl;
174     return 0;
175 }
176