src/video/android/SDL_androidevents.c
author Sylvain Becker <sylvain.becker@gmail.com>
Fri, 05 Apr 2019 09:16:30 +0200
changeset 12693 d311fcb8066a
parent 12562 d21956a01eed
child 12703 f6c7e5e03f60
permissions -rw-r--r--
Android: add hint SDL_HINT_ANDROID_BLOCK_ON_PAUSE
to set whether the event loop will block itself when the app is paused.
paul@4701
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@12503
     3
  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
paul@4701
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
paul@4701
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
paul@4701
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
paul@4701
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
paul@4701
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_ANDROID
slouken@6044
    24
paul@4713
    25
#include "SDL_androidevents.h"
gabomdq@6469
    26
#include "SDL_events.h"
slouken@12533
    27
#include "SDL_androidkeyboard.h"
gabomdq@7659
    28
#include "SDL_androidwindow.h"
gabomdq@7659
    29
slouken@10672
    30
/* Can't include sysaudio "../../audio/android/SDL_androidaudio.h"
slouken@10672
    31
 * because of THIS redefinition */
sylvain@12541
    32
sylvain@12541
    33
#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_ANDROID
slouken@10672
    34
extern void ANDROIDAUDIO_ResumeDevices(void);
slouken@10672
    35
extern void ANDROIDAUDIO_PauseDevices(void);
slouken@11900
    36
#else
slouken@11900
    37
static void ANDROIDAUDIO_ResumeDevices(void) {}
slouken@11900
    38
static void ANDROIDAUDIO_PauseDevices(void) {}
slouken@11900
    39
#endif
gabomdq@9148
    40
sylvain@12541
    41
#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_OPENSLES
sylvain@12541
    42
extern void openslES_ResumeDevices(void);
sylvain@12541
    43
extern void openslES_PauseDevices(void);
sylvain@12541
    44
#else
sylvain@12541
    45
static void openslES_ResumeDevices(void) {}
sylvain@12541
    46
static void openslES_PauseDevices(void) {}
sylvain@12541
    47
#endif
sylvain@12541
    48
sylvain@12506
    49
/* Number of 'type' events in the event queue */
sylvain@12505
    50
static int
sylvain@12506
    51
SDL_NumberOfEvents(Uint32 type)
sylvain@12505
    52
{
sylvain@12505
    53
    return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
sylvain@12505
    54
}
sylvain@12505
    55
sylvain@12496
    56
static void
sylvain@12496
    57
android_egl_context_restore(SDL_Window *window)
gabomdq@7659
    58
{
sylvain@12552
    59
    if (window) {
sylvain@12552
    60
        SDL_Event event;
sylvain@12552
    61
        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
sylvain@12552
    62
        if (SDL_GL_MakeCurrent(window, (SDL_GLContext) data->egl_context) < 0) {
sylvain@12552
    63
            /* The context is no longer valid, create a new one */
sylvain@12552
    64
            data->egl_context = (EGLContext) SDL_GL_CreateContext(window);
sylvain@12552
    65
            SDL_GL_MakeCurrent(window, (SDL_GLContext) data->egl_context);
sylvain@12552
    66
            event.type = SDL_RENDER_DEVICE_RESET;
sylvain@12552
    67
            SDL_PushEvent(&event);
sylvain@12552
    68
        }
gabomdq@7659
    69
    }
gabomdq@7659
    70
}
gabomdq@7659
    71
sylvain@12496
    72
static void
sylvain@12496
    73
android_egl_context_backup(SDL_Window *window)
gabomdq@7659
    74
{
sylvain@12552
    75
    if (window) {
sylvain@12552
    76
        /* Keep a copy of the EGL Context so we can try to restore it when we resume */
sylvain@12552
    77
        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
sylvain@12552
    78
        data->egl_context = SDL_GL_GetCurrentContext();
sylvain@12552
    79
        /* We need to do this so the EGLSurface can be freed */
sylvain@12552
    80
        SDL_GL_MakeCurrent(window, NULL);
sylvain@12552
    81
    }
gabomdq@7659
    82
}
paul@4713
    83
sylvain@12500
    84
sylvain@12500
    85
/*
sylvain@12500
    86
 * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
sylvain@12693
    87
 * When the pause semaphore is signaled, if Android_PumpEvents_Blocking is used, the event loop will block until the resume signal is emitted.
sylvain@12500
    88
 *
sylvain@12500
    89
 * No polling necessary
sylvain@12500
    90
 */
sylvain@12500
    91
paul@4701
    92
void
sylvain@12693
    93
Android_PumpEvents_Blocking(_THIS)
paul@4701
    94
{
sylvain@12552
    95
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
gabomdq@6330
    96
sylvain@12552
    97
    if (videodata->isPaused) {
gabomdq@6469
    98
gabomdq@7795
    99
        /* Make sure this is the last thing we do before pausing */
sylvain@12498
   100
        SDL_LockMutex(Android_ActivityMutex);
sylvain@12494
   101
        android_egl_context_backup(Android_Window);
sylvain@12498
   102
        SDL_UnlockMutex(Android_ActivityMutex);
sylvain@12496
   103
icculus@10281
   104
        ANDROIDAUDIO_PauseDevices();
sylvain@12541
   105
        openslES_PauseDevices();
sylvain@12500
   106
sylvain@12494
   107
        if (SDL_SemWait(Android_ResumeSem) == 0) {
sylvain@12500
   108
sylvain@12552
   109
            videodata->isPaused = 0;
sylvain@12500
   110
icculus@10281
   111
            ANDROIDAUDIO_ResumeDevices();
sylvain@12541
   112
            openslES_ResumeDevices();
sylvain@12500
   113
gabomdq@7659
   114
            /* Restore the GL Context from here, as this operation is thread dependent */
gabomdq@7910
   115
            if (!SDL_HasEvent(SDL_QUIT)) {
sylvain@12498
   116
                SDL_LockMutex(Android_ActivityMutex);
sylvain@12494
   117
                android_egl_context_restore(Android_Window);
sylvain@12498
   118
                SDL_UnlockMutex(Android_ActivityMutex);
gabomdq@7910
   119
            }
sylvain@12509
   120
sylvain@12509
   121
            /* Make sure SW Keyboard is restored when an app becomes foreground */
sylvain@12509
   122
            if (SDL_IsTextInputActive()) {
sylvain@12509
   123
                Android_StartTextInput(_this); /* Only showTextInput */
sylvain@12509
   124
            }
gabomdq@6330
   125
        }
sylvain@12500
   126
    } else {
sylvain@12552
   127
        if (videodata->isPausing || SDL_SemTryWait(Android_PauseSem) == 0) {
sylvain@12505
   128
            /* We've been signaled to pause (potentially several times), but before we block ourselves,
sylvain@12505
   129
             * we need to make sure that the very last event (of the first pause sequence, if several)
sylvain@12505
   130
             * has reached the app */
sylvain@12506
   131
            if (SDL_NumberOfEvents(SDL_APP_DIDENTERBACKGROUND) > SDL_SemValue(Android_PauseSem)) {
sylvain@12552
   132
                videodata->isPausing = 1;
gabomdq@6469
   133
            }
gabomdq@6469
   134
            else {
sylvain@12552
   135
                videodata->isPausing = 0;
sylvain@12552
   136
                videodata->isPaused = 1;
gabomdq@6469
   137
            }
gabomdq@6469
   138
        }
sylvain@12500
   139
    }
sylvain@12500
   140
}
sylvain@12500
   141
sylvain@12500
   142
void
sylvain@12693
   143
Android_PumpEvents_NonBlocking(_THIS)
sylvain@12500
   144
{
sylvain@12552
   145
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
sylvain@12500
   146
sylvain@12552
   147
    if (videodata->isPaused) {
sylvain@12500
   148
        if (SDL_SemTryWait(Android_ResumeSem) == 0) {
sylvain@12500
   149
sylvain@12552
   150
            videodata->isPaused = 0;
sylvain@12500
   151
sylvain@12500
   152
            ANDROIDAUDIO_ResumeDevices();
sylvain@12541
   153
            openslES_ResumeDevices();
sylvain@12500
   154
sylvain@12500
   155
            /* Restore the GL Context from here, as this operation is thread dependent */
sylvain@12500
   156
            if (!SDL_HasEvent(SDL_QUIT)) {
sylvain@12500
   157
                SDL_LockMutex(Android_ActivityMutex);
sylvain@12500
   158
                android_egl_context_restore(Android_Window);
sylvain@12500
   159
                SDL_UnlockMutex(Android_ActivityMutex);
sylvain@12500
   160
            }
sylvain@12509
   161
sylvain@12509
   162
            /* Make sure SW Keyboard is restored when an app becomes foreground */
sylvain@12509
   163
            if (SDL_IsTextInputActive()) {
sylvain@12509
   164
                Android_StartTextInput(_this); /* Only showTextInput */
sylvain@12509
   165
            }
sylvain@12500
   166
        }
sylvain@12500
   167
    } else {
sylvain@12494
   168
        if (SDL_SemTryWait(Android_PauseSem) == 0) {
sylvain@12500
   169
sylvain@12498
   170
            SDL_LockMutex(Android_ActivityMutex);
sylvain@12494
   171
            android_egl_context_backup(Android_Window);
sylvain@12498
   172
            SDL_UnlockMutex(Android_ActivityMutex);
sylvain@12496
   173
icculus@10281
   174
            ANDROIDAUDIO_PauseDevices();
sylvain@12541
   175
            openslES_PauseDevices();
sylvain@12500
   176
sylvain@12552
   177
            videodata->isPaused = 1;
gabomdq@6330
   178
        }
gabomdq@6330
   179
    }
paul@4713
   180
}
paul@4713
   181
slouken@6044
   182
#endif /* SDL_VIDEO_DRIVER_ANDROID */
slouken@6044
   183
paul@4701
   184
/* vi: set ts=4 sw=4 expandtab: */