Skip to content

Commit 2d43095

Browse files
committed
fix possible rendering edge cases
1 parent 7ecb18d commit 2d43095

File tree

3 files changed

+188
-50
lines changed

3 files changed

+188
-50
lines changed

NativeApp/include/Android/AndroidAppBase.hpp

+37-8
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,24 @@
1212
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1313
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
1414
*
15-
* In no event and under no legal theory, whether in tort (including negligence),
16-
* contract, or otherwise, unless required by applicable law (such as deliberate
15+
* In no event and under no legal theory, whether in tort (including negligence),
16+
* contract, or otherwise, unless required by applicable law (such as deliberate
1717
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
18-
* liable for any damages, including any direct, indirect, special, incidental,
19-
* or consequential damages of any character arising as a result of this License or
20-
* out of the use or inability to use the software (including but not limited to damages
21-
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
22-
* all other commercial damages or losses), even if such Contributor has been advised
18+
* liable for any damages, including any direct, indirect, special, incidental,
19+
* or consequential damages of any character arising as a result of this License or
20+
* out of the use or inability to use the software (including but not limited to damages
21+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
22+
* all other commercial damages or losses), even if such Contributor has been advised
2323
* of the possibility of such damages.
2424
*/
2525

2626
#pragma once
2727

2828
#include <memory>
29+
#include <mutex>
2930

3031
#include <android_native_app_glue.h>
32+
#include <FlagEnum.h>
3133
#include "AppBase.hpp"
3234

3335
#include "NDKHelper.h"
@@ -52,6 +54,27 @@ class AndroidAppBase : public AppBase
5254
static int32_t HandleInput(android_app* app, AInputEvent* event);
5355
static void HandleCmd(android_app* app, int32_t cmd);
5456

57+
enum APP_STATUS_FLAGS
58+
{
59+
APP_STATUS_FLAG_NONE = 0x00000000,
60+
61+
// Android lifecycle status flags. Not app-specific
62+
// Set between onCreate and onDestroy
63+
APP_STATUS_FLAG_RUNNING = 0x00000001,
64+
65+
// Set between onResume and onPause
66+
APP_STATUS_FLAG_ACTIVE = 0x00000002,
67+
68+
// Set between onWindowFocusChanged(true) and (false)
69+
APP_STATUS_FLAG_FOCUSED = 0x00000004,
70+
71+
// Set when the app's SurfaceHolder points to a
72+
// valid, nonzero-sized surface
73+
APP_STATUS_FLAG_HAS_REAL_SURFACE = 0x00000008
74+
};
75+
76+
APP_STATUS_FLAGS app_status_ = APP_STATUS_FLAG_NONE;
77+
5578
protected:
5679
virtual void Initialize()
5780
{
@@ -81,6 +104,8 @@ class AndroidAppBase : public AppBase
81104
android_app* app_ = nullptr;
82105
std::string native_activity_class_name_;
83106

107+
std::mutex mutex;
108+
84109
private:
85110
void UpdatePosition(AInputEvent* event, int32_t iIndex, float& fX, float& fY);
86111
void SuspendSensors();
@@ -89,11 +114,15 @@ class AndroidAppBase : public AppBase
89114
void UpdateFPS(float fFPS);
90115

91116
bool initialized_resources_ = false;
92-
bool has_focus_ = false;
117+
118+
int32_t window_width_ = 0;
119+
int32_t window_height_ = 0;
93120

94121
ASensorManager* sensor_manager_ = nullptr;
95122
const ASensor* accelerometer_sensor_ = nullptr;
96123
ASensorEventQueue* sensor_event_queue_ = nullptr;
97124
};
98125

126+
DEFINE_FLAG_ENUM_OPERATORS(AndroidAppBase::APP_STATUS_FLAGS)
127+
99128
} // namespace Diligent

NativeApp/src/Android/AndroidAppBase.cpp

+148-42
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@
1212
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1313
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
1414
*
15-
* In no event and under no legal theory, whether in tort (including negligence),
16-
* contract, or otherwise, unless required by applicable law (such as deliberate
15+
* In no event and under no legal theory, whether in tort (including negligence),
16+
* contract, or otherwise, unless required by applicable law (such as deliberate
1717
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
18-
* liable for any damages, including any direct, indirect, special, incidental,
19-
* or consequential damages of any character arising as a result of this License or
20-
* out of the use or inability to use the software (including but not limited to damages
21-
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
22-
* all other commercial damages or losses), even if such Contributor has been advised
18+
* liable for any damages, including any direct, indirect, special, incidental,
19+
* or consequential damages of any character arising as a result of this License or
20+
* out of the use or inability to use the software (including but not limited to damages
21+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
22+
* all other commercial damages or losses), even if such Contributor has been advised
2323
* of the possibility of such damages.
2424
*/
2525

2626
#include "AndroidAppBase.hpp"
27+
#include "Errors.hpp"
2728
#include "Timer.hpp"
2829

2930
#include <android/sensor.h>
@@ -118,22 +119,60 @@ void AndroidAppBase::HandleCmd(struct android_app* app, int32_t cmd)
118119
AndroidAppBase* eng = (AndroidAppBase*)app->userData;
119120
switch (cmd)
120121
{
121-
case APP_CMD_SAVE_STATE:
122-
break;
123-
124122
case APP_CMD_INIT_WINDOW:
125-
// The window is being shown, get it ready.
126-
if (app->window != NULL)
123+
#if (DILIGENT_DEVLOPMENT)
124+
LOG_INFO_MESSAGE("APP_CMD_INIT_WINDOW");
125+
#endif
126+
app->window = app->pendingWindow;
127+
if (app->window &&
128+
ANativeWindow_getWidth(app->window) &&
129+
ANativeWindow_getHeight(app->window))
127130
{
131+
#if (DILIGENT_DEVLOPMENT)
132+
LOG_INFO_MESSAGE("INIT DISPLAY - HAS SURFACE");
133+
#endif
128134
eng->InitDisplay();
129135
eng->DrawFrame();
136+
std::lock_guard<std::mutex> lock(eng->mutex);
137+
eng->app_status_ |= APP_STATUS_FLAG_HAS_REAL_SURFACE;
138+
}
139+
else
140+
{
141+
#if (DILIGENT_DEVLOPMENT)
142+
LOG_INFO_MESSAGE("LOST SURFACE");
143+
#endif
144+
std::lock_guard<std::mutex> lock(eng->mutex);
145+
eng->app_status_ &= ~APP_STATUS_FLAG_HAS_REAL_SURFACE;
130146
}
131147
break;
132148

133-
case APP_CMD_CONFIG_CHANGED:
149+
case APP_CMD_TERM_WINDOW:
150+
#if (DILIGENT_DEVLOPMENT)
151+
LOG_INFO_MESSAGE("APP_CMD_TERM_WINDOW - LOST SURFACE");
152+
#endif
153+
{
154+
std::lock_guard<std::mutex> lock(eng->mutex);
155+
eng->app_status_ &= ~APP_STATUS_FLAG_HAS_REAL_SURFACE;
156+
}
157+
#if (DILIGENT_DEVLOPMENT)
158+
LOG_INFO_MESSAGE("TERM DISPLAY");
159+
#endif
160+
eng->TermDisplay();
161+
break;
162+
163+
// Note that as of NDK r21b (21.1.6352462), APP_CMD_CONTENT_RECT_CHANGED event is never
164+
// generated by android_native_app_glue
165+
case APP_CMD_CONTENT_RECT_CHANGED:
134166
{
135-
// This callback is not reliable for handling orientation changes. Depending on the
136-
// device, it may be called before or after the surface has been actually resized.
167+
#if (DILIGENT_DEVLOPMENT)
168+
LOG_INFO_MESSAGE("APP_CMD_CONTENT_RECT_CHANGED");
169+
#endif
170+
171+
int32_t new_window_width =
172+
app->contentRect.right - app->contentRect.left;
173+
int32_t new_window_height =
174+
app->contentRect.bottom - app->contentRect.top;
175+
eng->WindowResize(new_window_width, new_window_height);
137176
break;
138177
}
139178

@@ -144,45 +183,111 @@ void AndroidAppBase::HandleCmd(struct android_app* app, int32_t cmd)
144183
// does not work either - the callback is only called once after the window has been created.
145184
case APP_CMD_WINDOW_RESIZED:
146185
{
147-
auto new_window_width = ANativeWindow_getWidth(app->window);
148-
auto new_window_height = ANativeWindow_getHeight(app->window);
149-
eng->WindowResize(new_window_width, new_window_height);
186+
#if (DILIGENT_DEVLOPMENT)
187+
LOG_INFO_MESSAGE("APP_CMD_WINDOW_RESIZED");
188+
#endif
189+
if (app->window)
190+
{
191+
int32_t new_window_width = ANativeWindow_getWidth(app->window);
192+
int32_t new_window_height = ANativeWindow_getHeight(app->window);
193+
if (new_window_width && new_window_height)
194+
{
195+
eng->WindowResize(new_window_width, new_window_height);
196+
}
197+
}
150198
break;
151199
}
152200

153-
// Note that as of NDK r21b (21.1.6352462), APP_CMD_CONTENT_RECT_CHANGED event is never
154-
// generated by android_native_app_glue
155-
case APP_CMD_CONTENT_RECT_CHANGED:
156-
{
157-
auto new_window_width = app->contentRect.right - app->contentRect.left;
158-
auto new_window_height = app->contentRect.bottom - app->contentRect.top;
159-
eng->WindowResize(new_window_width, new_window_height);
201+
case APP_CMD_GAINED_FOCUS:
202+
#if (DILIGENT_DEVLOPMENT)
203+
LOG_INFO_MESSAGE("APP_CMD_GAINED_FOCUS - HAS FOCUS");
204+
#endif
205+
{
206+
std::lock_guard<std::mutex> lock(eng->mutex);
207+
eng->app_status_ |= APP_STATUS_FLAG_FOCUSED;
208+
}
209+
eng->ResumeSensors();
210+
break;
211+
212+
case APP_CMD_LOST_FOCUS:
213+
#if (DILIGENT_DEVLOPMENT)
214+
LOG_INFO_MESSAGE("APP_CMD_LOST_FOCUS - LOST FOCUS");
215+
#endif
216+
{
217+
std::lock_guard<std::mutex> lock(eng->mutex);
218+
eng->app_status_ &= ~APP_STATUS_FLAG_FOCUSED;
219+
}
220+
eng->SuspendSensors();
221+
break;
222+
223+
case APP_CMD_RESUME:
224+
#if (DILIGENT_DEVLOPMENT)
225+
LOG_INFO_MESSAGE("APP_CMD_RESUME - IS ACTIVE");
226+
#endif
227+
{
228+
std::lock_guard<std::mutex> lock(eng->mutex);
229+
eng->app_status_ |= APP_STATUS_FLAG_ACTIVE;
230+
}
231+
break;
232+
233+
case APP_CMD_START:
234+
#if (DILIGENT_DEVLOPMENT)
235+
LOG_INFO_MESSAGE("APP_CMD_START");
236+
#endif
160237
break;
161-
}
162238

163-
case APP_CMD_TERM_WINDOW:
164239
case APP_CMD_PAUSE:
165-
// The window is being hidden or closed, clean it up.
166-
eng->TermDisplay();
167-
eng->has_focus_ = false;
240+
#if (DILIGENT_DEVLOPMENT)
241+
LOG_INFO_MESSAGE("APP_CMD_PAUSE - IS NOT ACTIVE");
242+
#endif
243+
{
244+
std::lock_guard<std::mutex> lock(eng->mutex);
245+
eng->app_status_ &= ~APP_STATUS_FLAG_ACTIVE;
246+
}
168247
break;
169248

170249
case APP_CMD_STOP:
250+
#if (DILIGENT_DEVLOPMENT)
251+
LOG_INFO_MESSAGE("APP_CMD_STOP");
252+
#endif
171253
break;
172254

173-
case APP_CMD_GAINED_FOCUS:
174-
eng->ResumeSensors();
175-
//Start animation
176-
eng->has_focus_ = true;
255+
case APP_CMD_CONFIG_CHANGED:
256+
#if (DILIGENT_DEVLOPMENT)
257+
LOG_INFO_MESSAGE("APP_CMD_CONFIG_CHANGED");
258+
#endif
259+
// AConfiguration_fromAssetManager(app->config, app->activity->assetManager);
260+
// This callback is not reliable for handling orientation changes. Depending on the
261+
// device, it may be called before or after the surface has been actually resized.
177262
break;
178263

179-
case APP_CMD_LOST_FOCUS:
180-
eng->SuspendSensors();
181-
// Also stop animating.
182-
eng->has_focus_ = false;
264+
case APP_CMD_DESTROY:
265+
#if (DILIGENT_DEVLOPMENT)
266+
LOG_INFO_MESSAGE("APP_CMD_DESTROY - IS NOT RUNNING");
267+
#endif
268+
{
269+
std::lock_guard<std::mutex> lock(eng->mutex);
270+
eng->app_status_ &= ~APP_STATUS_FLAG_RUNNING;
271+
}
272+
break;
273+
274+
case APP_CMD_WINDOW_REDRAW_NEEDED:
275+
#if (DILIGENT_DEVLOPMENT)
276+
LOG_INFO_MESSAGE("APP_CMD_WINDOW_REDRAW_NEEDED");
277+
#endif
278+
if (eng->IsReady()) eng->DrawFrame();
279+
break;
280+
281+
case APP_CMD_SAVE_STATE:
282+
#if (DILIGENT_DEVLOPMENT)
283+
LOG_INFO_MESSAGE("APP_CMD_SAVE_STATE");
284+
#endif
183285
break;
184286

185287
case APP_CMD_LOW_MEMORY:
288+
#if (DILIGENT_DEVLOPMENT)
289+
LOG_INFO_MESSAGE("APP_CMD_LOW_MEMORY");
290+
#endif
186291
//Free up GL resources
187292
eng->TrimMemory();
188293
break;
@@ -244,10 +349,11 @@ void AndroidAppBase::SetState(android_app* state, const char* native_activity_cl
244349

245350
bool AndroidAppBase::IsReady()
246351
{
247-
if (has_focus_)
248-
return true;
249-
250-
return false;
352+
std::lock_guard<std::mutex> lock(mutex);
353+
return (app_status_ & APP_STATUS_FLAG_RUNNING) != APP_STATUS_FLAG_NONE &&
354+
(app_status_ & APP_STATUS_FLAG_ACTIVE) != APP_STATUS_FLAG_NONE &&
355+
(app_status_ & APP_STATUS_FLAG_FOCUSED) != APP_STATUS_FLAG_NONE &&
356+
(app_status_ & APP_STATUS_FLAG_HAS_REAL_SURFACE) != APP_STATUS_FLAG_NONE;
251357
}
252358

253359
//void Engine::TransformPosition( ndk_helper::Vec2& vec )

NativeApp/src/Android/AndroidMain.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ using namespace Diligent;
4242
void android_main(android_app* state)
4343
{
4444
std::unique_ptr<AndroidAppBase> theApp(CreateApplication());
45+
46+
theApp->app_status_ |= AndroidAppBase::APP_STATUS_FLAG_RUNNING;
47+
4548
theApp->SetState(state, NATIVEACTIVITY_CLASS_NAME);
4649

4750
//Init helper functions

0 commit comments

Comments
 (0)