mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Only join a previous command thread and restart if it has exited
* APP_CMD_INIT_WINDOW can be called when the application hasn't fully shutdown, and the thread is still running. Hold a lock while we're inside renderdoccmd() so that we know if the thread has exited or not. * This would be easier if android had pthread_tryjoin_np()...
This commit is contained in:
@@ -47,11 +47,26 @@ using std::istringstream;
|
||||
struct android_app *android_state;
|
||||
pthread_t cmdthread_handle = 0;
|
||||
|
||||
struct
|
||||
struct PThreadLock
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
pthread_mutexattr_t attr;
|
||||
} m_DrawLock;
|
||||
void init()
|
||||
{
|
||||
pthread_mutexattr_init(&mutexattr);
|
||||
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex, &mutexattr);
|
||||
}
|
||||
void destroy()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
pthread_mutexattr_destroy(&mutexattr);
|
||||
}
|
||||
bool trylock() { return pthread_mutex_trylock(&mutex) == 0; };
|
||||
void lock() { pthread_mutex_lock(&mutex); }
|
||||
void unlock() { pthread_mutex_unlock(&mutex); }
|
||||
private:
|
||||
pthread_mutex_t mutex;
|
||||
pthread_mutexattr_t mutexattr;
|
||||
} m_DrawLock, m_CmdLock;
|
||||
|
||||
void Daemonise()
|
||||
{
|
||||
@@ -60,7 +75,7 @@ void Daemonise()
|
||||
void DisplayGenericSplash()
|
||||
{
|
||||
// if something else is drawing and holding the lock, then bail
|
||||
if(pthread_mutex_trylock(&m_DrawLock.lock))
|
||||
if(!m_DrawLock.trylock())
|
||||
return;
|
||||
|
||||
// since we're not pumping this continually and we only draw when we need to, we can just do the
|
||||
@@ -275,7 +290,7 @@ void main()
|
||||
|
||||
dlclose(libEGL);
|
||||
|
||||
pthread_mutex_unlock(&m_DrawLock.lock);
|
||||
m_DrawLock.unlock();
|
||||
}
|
||||
|
||||
WindowingData DisplayRemoteServerPreview(bool active, const rdcarray<WindowingSystem> &systems)
|
||||
@@ -290,11 +305,11 @@ WindowingData DisplayRemoteServerPreview(bool active, const rdcarray<WindowingSy
|
||||
// if we're opening it, aquire the draw lock, otherwise release it.
|
||||
if(active)
|
||||
{
|
||||
pthread_mutex_lock(&m_DrawLock.lock);
|
||||
m_DrawLock.lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&m_DrawLock.lock);
|
||||
m_DrawLock.unlock();
|
||||
|
||||
// when we release it, re-draw the splash
|
||||
DisplayGenericSplash();
|
||||
@@ -314,7 +329,7 @@ void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &display
|
||||
{
|
||||
ANativeWindow *connectionScreenWindow = android_state->window;
|
||||
|
||||
pthread_mutex_lock(&m_DrawLock.lock);
|
||||
m_DrawLock.lock();
|
||||
|
||||
IReplayOutput *out = renderer->CreateOutput(CreateAndroidWindowingData(connectionScreenWindow),
|
||||
ReplayOutputType::Texture);
|
||||
@@ -331,7 +346,7 @@ void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &display
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&m_DrawLock.lock);
|
||||
m_DrawLock.unlock();
|
||||
}
|
||||
|
||||
// Returns the renderdoccmd arguments passed via am start
|
||||
@@ -377,7 +392,11 @@ void *cmdthread(void *)
|
||||
{
|
||||
vector<string> args = getRenderdoccmdArgs();
|
||||
if(args.size())
|
||||
{
|
||||
m_CmdLock.lock();
|
||||
renderdoccmd(GlobalEnvironment(), args);
|
||||
m_CmdLock.unlock();
|
||||
}
|
||||
|
||||
// activity is done and should be closed
|
||||
ANativeActivity_finish(android_state->activity);
|
||||
@@ -391,11 +410,26 @@ void handle_cmd(android_app *app, int32_t cmd)
|
||||
{
|
||||
case APP_CMD_INIT_WINDOW:
|
||||
{
|
||||
// if we already have a thread handle, see if it's still running
|
||||
if(cmdthread_handle != 0)
|
||||
// If user resumes APK after server shutdown, restart the thread.
|
||||
pthread_join(cmdthread_handle, NULL);
|
||||
{
|
||||
// if the thread isn't running anymore, we can acquire m_CmdLock. If so, we need to join the
|
||||
// thread and start afresh. If we can't acquire the lock, the thread is still running so we
|
||||
// leave it alone.
|
||||
if(m_CmdLock.trylock())
|
||||
{
|
||||
m_CmdLock.unlock();
|
||||
// safe to join here, thread will terminate soon if it hasn't already
|
||||
pthread_join(cmdthread_handle, NULL);
|
||||
cmdthread_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_create(&cmdthread_handle, NULL, cmdthread, NULL);
|
||||
// if we don't have a command thread, start one.
|
||||
if(cmdthread_handle == 0)
|
||||
pthread_create(&cmdthread_handle, NULL, cmdthread, NULL);
|
||||
|
||||
DisplayGenericSplash();
|
||||
break;
|
||||
}
|
||||
case APP_CMD_WINDOW_REDRAW_NEEDED:
|
||||
@@ -413,9 +447,8 @@ void android_main(struct android_app *state)
|
||||
android_state = state;
|
||||
android_state->onAppCmd = handle_cmd;
|
||||
|
||||
pthread_mutexattr_init(&m_DrawLock.attr);
|
||||
pthread_mutexattr_settype(&m_DrawLock.attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&m_DrawLock.lock, &m_DrawLock.attr);
|
||||
m_DrawLock.init();
|
||||
m_CmdLock.init();
|
||||
|
||||
ANDROID_LOG("android_main android_state->window: %p", android_state->window);
|
||||
|
||||
@@ -433,6 +466,6 @@ void android_main(struct android_app *state)
|
||||
|
||||
ANDROID_LOG("android_main exiting");
|
||||
|
||||
pthread_mutex_destroy(&m_DrawLock.lock);
|
||||
pthread_mutexattr_destroy(&m_DrawLock.attr);
|
||||
m_DrawLock.destroy();
|
||||
m_CmdLock.destroy();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user