Skip to content

Commit

Permalink
fix possible rendering edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
mgood7123 committed Jun 28, 2021
1 parent 7ecb18d commit 2d43095
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 50 deletions.
45 changes: 37 additions & 8 deletions NativeApp/include/Android/AndroidAppBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#pragma once

#include <memory>
#include <mutex>

#include <android_native_app_glue.h>
#include <FlagEnum.h>
#include "AppBase.hpp"

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

enum APP_STATUS_FLAGS
{
APP_STATUS_FLAG_NONE = 0x00000000,

// Android lifecycle status flags. Not app-specific
// Set between onCreate and onDestroy
APP_STATUS_FLAG_RUNNING = 0x00000001,

// Set between onResume and onPause
APP_STATUS_FLAG_ACTIVE = 0x00000002,

// Set between onWindowFocusChanged(true) and (false)
APP_STATUS_FLAG_FOCUSED = 0x00000004,

// Set when the app's SurfaceHolder points to a
// valid, nonzero-sized surface
APP_STATUS_FLAG_HAS_REAL_SURFACE = 0x00000008
};

APP_STATUS_FLAGS app_status_ = APP_STATUS_FLAG_NONE;

protected:
virtual void Initialize()
{
Expand Down Expand Up @@ -81,6 +104,8 @@ class AndroidAppBase : public AppBase
android_app* app_ = nullptr;
std::string native_activity_class_name_;

std::mutex mutex;

private:
void UpdatePosition(AInputEvent* event, int32_t iIndex, float& fX, float& fY);
void SuspendSensors();
Expand All @@ -89,11 +114,15 @@ class AndroidAppBase : public AppBase
void UpdateFPS(float fFPS);

bool initialized_resources_ = false;
bool has_focus_ = false;

int32_t window_width_ = 0;
int32_t window_height_ = 0;

ASensorManager* sensor_manager_ = nullptr;
const ASensor* accelerometer_sensor_ = nullptr;
ASensorEventQueue* sensor_event_queue_ = nullptr;
};

DEFINE_FLAG_ENUM_OPERATORS(AndroidAppBase::APP_STATUS_FLAGS)

} // namespace Diligent
190 changes: 148 additions & 42 deletions NativeApp/src/Android/AndroidAppBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#include "AndroidAppBase.hpp"
#include "Errors.hpp"
#include "Timer.hpp"

#include <android/sensor.h>
Expand Down Expand Up @@ -118,22 +119,60 @@ void AndroidAppBase::HandleCmd(struct android_app* app, int32_t cmd)
AndroidAppBase* eng = (AndroidAppBase*)app->userData;
switch (cmd)
{
case APP_CMD_SAVE_STATE:
break;

case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
if (app->window != NULL)
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_INIT_WINDOW");
#endif
app->window = app->pendingWindow;
if (app->window &&
ANativeWindow_getWidth(app->window) &&
ANativeWindow_getHeight(app->window))
{
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("INIT DISPLAY - HAS SURFACE");
#endif
eng->InitDisplay();
eng->DrawFrame();
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ |= APP_STATUS_FLAG_HAS_REAL_SURFACE;
}
else
{
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("LOST SURFACE");
#endif
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ &= ~APP_STATUS_FLAG_HAS_REAL_SURFACE;
}
break;

case APP_CMD_CONFIG_CHANGED:
case APP_CMD_TERM_WINDOW:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_TERM_WINDOW - LOST SURFACE");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ &= ~APP_STATUS_FLAG_HAS_REAL_SURFACE;
}
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("TERM DISPLAY");
#endif
eng->TermDisplay();
break;

// Note that as of NDK r21b (21.1.6352462), APP_CMD_CONTENT_RECT_CHANGED event is never
// generated by android_native_app_glue
case APP_CMD_CONTENT_RECT_CHANGED:
{
// This callback is not reliable for handling orientation changes. Depending on the
// device, it may be called before or after the surface has been actually resized.
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_CONTENT_RECT_CHANGED");
#endif

int32_t new_window_width =
app->contentRect.right - app->contentRect.left;
int32_t new_window_height =
app->contentRect.bottom - app->contentRect.top;
eng->WindowResize(new_window_width, new_window_height);
break;
}

Expand All @@ -144,45 +183,111 @@ void AndroidAppBase::HandleCmd(struct android_app* app, int32_t cmd)
// does not work either - the callback is only called once after the window has been created.
case APP_CMD_WINDOW_RESIZED:
{
auto new_window_width = ANativeWindow_getWidth(app->window);
auto new_window_height = ANativeWindow_getHeight(app->window);
eng->WindowResize(new_window_width, new_window_height);
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_WINDOW_RESIZED");
#endif
if (app->window)
{
int32_t new_window_width = ANativeWindow_getWidth(app->window);
int32_t new_window_height = ANativeWindow_getHeight(app->window);
if (new_window_width && new_window_height)
{
eng->WindowResize(new_window_width, new_window_height);
}
}
break;
}

// Note that as of NDK r21b (21.1.6352462), APP_CMD_CONTENT_RECT_CHANGED event is never
// generated by android_native_app_glue
case APP_CMD_CONTENT_RECT_CHANGED:
{
auto new_window_width = app->contentRect.right - app->contentRect.left;
auto new_window_height = app->contentRect.bottom - app->contentRect.top;
eng->WindowResize(new_window_width, new_window_height);
case APP_CMD_GAINED_FOCUS:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_GAINED_FOCUS - HAS FOCUS");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ |= APP_STATUS_FLAG_FOCUSED;
}
eng->ResumeSensors();
break;

case APP_CMD_LOST_FOCUS:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_LOST_FOCUS - LOST FOCUS");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ &= ~APP_STATUS_FLAG_FOCUSED;
}
eng->SuspendSensors();
break;

case APP_CMD_RESUME:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_RESUME - IS ACTIVE");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ |= APP_STATUS_FLAG_ACTIVE;
}
break;

case APP_CMD_START:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_START");
#endif
break;
}

case APP_CMD_TERM_WINDOW:
case APP_CMD_PAUSE:
// The window is being hidden or closed, clean it up.
eng->TermDisplay();
eng->has_focus_ = false;
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_PAUSE - IS NOT ACTIVE");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ &= ~APP_STATUS_FLAG_ACTIVE;
}
break;

case APP_CMD_STOP:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_STOP");
#endif
break;

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

case APP_CMD_LOST_FOCUS:
eng->SuspendSensors();
// Also stop animating.
eng->has_focus_ = false;
case APP_CMD_DESTROY:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_DESTROY - IS NOT RUNNING");
#endif
{
std::lock_guard<std::mutex> lock(eng->mutex);
eng->app_status_ &= ~APP_STATUS_FLAG_RUNNING;
}
break;

case APP_CMD_WINDOW_REDRAW_NEEDED:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_WINDOW_REDRAW_NEEDED");
#endif
if (eng->IsReady()) eng->DrawFrame();
break;

case APP_CMD_SAVE_STATE:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_SAVE_STATE");
#endif
break;

case APP_CMD_LOW_MEMORY:
#if (DILIGENT_DEVLOPMENT)
LOG_INFO_MESSAGE("APP_CMD_LOW_MEMORY");
#endif
//Free up GL resources
eng->TrimMemory();
break;
Expand Down Expand Up @@ -244,10 +349,11 @@ void AndroidAppBase::SetState(android_app* state, const char* native_activity_cl

bool AndroidAppBase::IsReady()
{
if (has_focus_)
return true;

return false;
std::lock_guard<std::mutex> lock(mutex);
return (app_status_ & APP_STATUS_FLAG_RUNNING) != APP_STATUS_FLAG_NONE &&
(app_status_ & APP_STATUS_FLAG_ACTIVE) != APP_STATUS_FLAG_NONE &&
(app_status_ & APP_STATUS_FLAG_FOCUSED) != APP_STATUS_FLAG_NONE &&
(app_status_ & APP_STATUS_FLAG_HAS_REAL_SURFACE) != APP_STATUS_FLAG_NONE;
}

//void Engine::TransformPosition( ndk_helper::Vec2& vec )
Expand Down
3 changes: 3 additions & 0 deletions NativeApp/src/Android/AndroidMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ using namespace Diligent;
void android_main(android_app* state)
{
std::unique_ptr<AndroidAppBase> theApp(CreateApplication());

theApp->app_status_ |= AndroidAppBase::APP_STATUS_FLAG_RUNNING;

theApp->SetState(state, NATIVEACTIVITY_CLASS_NAME);

//Init helper functions
Expand Down

0 comments on commit 2d43095

Please sign in to comment.