Line data Source code
1 : /**
2 : Copyright (c) 2020-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #include "XLDirector.h"
25 :
26 : #include "XLResourceCache.h"
27 : #include "XLScheduler.h"
28 : #include "XLScene.h"
29 : #include "XLInputDispatcher.h"
30 : #include "XLTextInputManager.h"
31 : #include "XLActionManager.h"
32 : #include "XLCoreLoop.h"
33 : #include "XLCoreFrameRequest.h"
34 : #include "XLView.h"
35 :
36 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
37 :
38 21 : Director::Director() {
39 21 : memset(&_drawStat, 0, sizeof(DrawStat));
40 21 : }
41 :
42 42 : Director::~Director() { }
43 :
44 21 : bool Director::init(Application *main, const core::FrameContraints &constraints, View *view) {
45 21 : _mainLoop = main;
46 21 : _view = view;
47 21 : _pool = Rc<PoolRef>::alloc();
48 21 : _pool->perform([&, this] {
49 21 : _scheduler = Rc<Scheduler>::create();
50 21 : _actionManager = Rc<ActionManager>::create();
51 21 : _inputDispatcher = Rc<InputDispatcher>::create(_pool, view);
52 21 : });
53 21 : _startTime = _mainLoop->getClock();
54 21 : _time.global = 0;
55 21 : _time.app = 0;
56 21 : _time.delta = 0;
57 :
58 21 : _constraints = constraints;
59 :
60 21 : updateGeneralTransform();
61 :
62 21 : return true;
63 : }
64 :
65 105 : TextInputManager *Director::getTextInputManager() const {
66 105 : return _inputDispatcher->getTextInputManager();
67 : }
68 :
69 47023 : const Rc<ResourceCache> &Director::getResourceCache() const {
70 47023 : return _mainLoop->getResourceCache();
71 : }
72 :
73 9538 : bool Director::acquireFrame(const Rc<FrameRequest> &req) {
74 9538 : if (!_scene) {
75 0 : return false;
76 : }
77 :
78 9538 : auto t = _mainLoop->getClock();
79 :
80 9538 : setFrameConstraints(req->getFrameConstraints());
81 :
82 9538 : update(t);
83 9538 : if (_scene) {
84 9538 : req->setQueue(_scene->getQueue());
85 : }
86 :
87 9538 : _mainLoop->performOnMainThread([this, req] {
88 9538 : if (!_scene) {
89 0 : return;
90 : }
91 :
92 9538 : req->getPool()->perform([&, this] {
93 9538 : _scene->renderRequest(req);
94 :
95 9538 : if (hasActiveInteractions()) {
96 9538 : _view->setReadyForNextFrame();
97 : }
98 9538 : });
99 : }, this, true);
100 :
101 9538 : _avgFrameTime.addValue(_mainLoop->getClock() - t);
102 9538 : _avgFrameTimeValue = _avgFrameTime.getAverage();
103 9538 : return true;
104 : }
105 :
106 9538 : void Director::update(uint64_t t) {
107 9538 : if (_time.global) {
108 9517 : _time.delta = t - _time.global;
109 : } else {
110 21 : _time.delta = 0;
111 : }
112 :
113 9538 : _time.global = t;
114 9538 : _time.app = t - _startTime;
115 :
116 : // If we are debugging our code, prevent big delta time
117 9538 : if (_time.delta && _time.delta > config::MaxDirectorDeltaTime) {
118 0 : _time.delta = config::MaxDirectorDeltaTime;
119 : }
120 :
121 9538 : _time.dt = float(_time.delta) / 1'000'000;
122 :
123 9538 : if (_nextScene) {
124 0 : if (_scene) {
125 0 : _scene->onFinished(this);
126 : }
127 0 : _scene = _nextScene;
128 :
129 0 : _scene->setFrameConstraints(_constraints);
130 0 : _scene->onPresented(this);
131 0 : _nextScene = nullptr;
132 : }
133 :
134 9538 : _inputDispatcher->update(_time);
135 9538 : _scheduler->update(_time);
136 9538 : _actionManager->update(_time);
137 :
138 9538 : _mainLoop->getResourceCache()->update(_time);
139 :
140 9538 : _autorelease.clear();
141 9538 : }
142 :
143 21 : void Director::end() {
144 : #if SP_REF_DEBUG
145 : if (_scene) {
146 : _scene->onFinished(this);
147 : }
148 : _autorelease.clear();
149 :
150 : if (_scene) {
151 : if (_scene->getReferenceCount() > 1) {
152 : auto scene = _scene.get();
153 : _scene = nullptr;
154 :
155 : scene->foreachBacktrace([] (uint64_t id, Time time, const std::vector<std::string> &vec) {
156 : StringStream stream;
157 : stream << "[" << id << ":" << time.toHttp<Interface>() << "]:\n";
158 : for (auto &it : vec) {
159 : stream << "\t" << it << "\n";
160 : }
161 : log::debug("Director", stream.str());
162 : });
163 : } else {
164 : _scene = nullptr;
165 : }
166 : }
167 :
168 : if (core::FrameHandle::GetActiveFramesCount()) {
169 : core::FrameHandle::DescribeActiveFrames();
170 : }
171 : #else
172 21 : if (_scene) {
173 21 : _scene->onFinished(this);
174 21 : _scene = nullptr;
175 : }
176 :
177 21 : if (!_scheduler->empty()) {
178 21 : _scheduler->unscheduleAll();
179 : }
180 :
181 21 : _nextScene = nullptr;
182 21 : _autorelease.clear();
183 : #endif
184 21 : }
185 :
186 19245 : core::Loop *Director::getGlLoop() const {
187 19245 : return _mainLoop->getGlLoop();
188 : }
189 :
190 9706 : void Director::setFrameConstraints(const core::FrameContraints &c) {
191 9706 : if (_constraints != c) {
192 168 : _constraints = c;
193 168 : if (_scene) {
194 168 : _scene->setFrameConstraints(_constraints);
195 : }
196 :
197 168 : updateGeneralTransform();
198 : }
199 9706 : }
200 :
201 21 : void Director::runScene(Rc<Scene> &&scene) {
202 21 : if (!scene) {
203 0 : return;
204 : }
205 :
206 21 : log::debug("Director", "runScene");
207 :
208 21 : auto linkId = retain();
209 21 : auto &queue = scene->getQueue();
210 21 : getGlLoop()->compileQueue(queue, [this, scene = move(scene), linkId, view = Rc<View>(_view)] (bool success) mutable {
211 21 : if (success) {
212 21 : _mainLoop->performOnMainThread([this, scene = move(scene), view] {
213 21 : _nextScene = scene;
214 21 : if (!_scene) {
215 21 : _scene = _nextScene;
216 21 : _nextScene = nullptr;
217 21 : _scene->setFrameConstraints(_constraints);
218 21 : updateGeneralTransform();
219 21 : _scene->onPresented(this);
220 21 : getGlLoop()->performOnGlThread([view, scene = _scene] {
221 21 : auto &q = scene->getQueue();
222 21 : view->runWithQueue(q);
223 21 : }, this);
224 : }
225 21 : }, this);
226 : }
227 21 : release(linkId);
228 21 : });
229 : }
230 :
231 9518 : void Director::pushDrawStat(const DrawStat &stat) {
232 9518 : _mainLoop->performOnMainThread([this, stat] {
233 9518 : _drawStat = stat;
234 9518 : }, this);
235 9518 : }
236 :
237 42 : float Director::getFps() const {
238 42 : return 1.0f / (_view->getLastFrameInterval() / 1000000.0f);
239 : }
240 :
241 9538 : float Director::getAvgFps() const {
242 9538 : return 1.0f / (_view->getAvgFrameInterval() / 1000000.0f);
243 : }
244 :
245 9538 : float Director::getSpf() const {
246 9538 : return _view->getLastFrameTime() / 1000.0f;
247 : }
248 :
249 9538 : float Director::getLocalFrameTime() const {
250 9538 : return _view->getAvgFenceTime() / 1000.0f;
251 : }
252 :
253 86279 : void Director::autorelease(Ref *ref) {
254 86279 : _autorelease.emplace_back(ref);
255 86279 : }
256 :
257 0 : void Director::invalidate() {
258 :
259 0 : }
260 :
261 210 : void Director::updateGeneralTransform() {
262 210 : auto transform = core::getPureTransform(_constraints.transform);
263 :
264 210 : Mat4 proj;
265 210 : switch (transform) {
266 21 : case core::SurfaceTransformFlags::Rotate90: proj = Mat4::ROTATION_Z_90; break;
267 21 : case core::SurfaceTransformFlags::Rotate180: proj = Mat4::ROTATION_Z_180; break;
268 21 : case core::SurfaceTransformFlags::Rotate270: proj = Mat4::ROTATION_Z_270; break;
269 21 : case core::SurfaceTransformFlags::Mirror: break;
270 21 : case core::SurfaceTransformFlags::MirrorRotate90: break;
271 21 : case core::SurfaceTransformFlags::MirrorRotate180: break;
272 21 : case core::SurfaceTransformFlags::MirrorRotate270: break;
273 63 : default: proj = Mat4::IDENTITY; break;
274 : }
275 :
276 210 : if ((_constraints.transform & core::SurfaceTransformFlags::PreRotated) != core::SurfaceTransformFlags::None) {
277 147 : switch (transform) {
278 84 : case core::SurfaceTransformFlags::Rotate90:
279 : case core::SurfaceTransformFlags::Rotate270:
280 : case core::SurfaceTransformFlags::MirrorRotate90:
281 : case core::SurfaceTransformFlags::MirrorRotate270:
282 84 : proj.scale(2.0f / _constraints.extent.height, -2.0f / _constraints.extent.width, -1.0);
283 84 : break;
284 63 : default:
285 63 : proj.scale(2.0f / _constraints.extent.width, -2.0f / _constraints.extent.height, -1.0);
286 63 : break;
287 : }
288 : } else {
289 63 : proj.scale(2.0f / _constraints.extent.width, -2.0f / _constraints.extent.height, -1.0);
290 : }
291 210 : proj.m[12] = -1.0;
292 210 : proj.m[13] = 1.0f;
293 210 : proj.m[14] = 0.0f;
294 210 : proj.m[15] = 1.0f;
295 :
296 210 : switch (transform) {
297 21 : case core::SurfaceTransformFlags::Rotate90: proj.m[13] = -1.0f; break;
298 21 : case core::SurfaceTransformFlags::Rotate180: proj.m[12] = 1.0f; proj.m[13] = -1.0f; break;
299 21 : case core::SurfaceTransformFlags::Rotate270: proj.m[12] = 1.0f; break;
300 21 : case core::SurfaceTransformFlags::Mirror: break;
301 21 : case core::SurfaceTransformFlags::MirrorRotate90: break;
302 21 : case core::SurfaceTransformFlags::MirrorRotate180: break;
303 21 : case core::SurfaceTransformFlags::MirrorRotate270: break;
304 63 : default: break;
305 : }
306 :
307 210 : _generalProjection = proj;
308 210 : }
309 :
310 9538 : bool Director::hasActiveInteractions() {
311 9538 : return !_actionManager->empty() || _inputDispatcher->hasActiveInput();
312 : }
313 :
314 : }
|