Wake up main thread immediately after new frame is pushed

This commit is contained in:
Cameron Gutman 2019-01-21 18:57:14 -08:00
parent 1f972b1828
commit aab7191a44
5 changed files with 70 additions and 11 deletions

View File

@ -126,7 +126,8 @@ SOURCES += \
path.cpp \
settings/mappingmanager.cpp \
gui/sdlgamepadkeynavigation.cpp \
streaming/video/overlaymanager.cpp
streaming/video/overlaymanager.cpp \
streaming/sdlhelper.cpp
HEADERS += \
utils.h \
@ -153,7 +154,8 @@ HEADERS += \
path.h \
settings/mappingmanager.h \
gui/sdlgamepadkeynavigation.h \
streaming/video/overlaymanager.h
streaming/video/overlaymanager.h \
streaming/sdlhelper.h
# Platform-specific renderers and decoders
ffmpeg {

View File

@ -0,0 +1,45 @@
#include "sdlhelper.h"
SDL_cond* SDLHelper::s_EventCond;
SDL_mutex* SDLHelper::s_EventMutex;
void SDLHelper::initializeIfNeeded()
{
if (!s_EventCond) {
s_EventCond = SDL_CreateCond();
}
if (!s_EventMutex) {
s_EventMutex = SDL_CreateMutex();
}
}
void SDLHelper::waitEvent(SDL_Event* event)
{
initializeIfNeeded();
// We explicitly use SDL_PollEvent() and SDL_Delay() because
// SDL_WaitEventTimeout() has an internal SDL_Delay(10) inside which
// blocks this thread too long for high polling rate mice and high
// refresh rate displays.
while (!SDL_PollEvent(event)) {
// Sleep for up to 1 ms or until we are woken up by
// SDLHelper::pushEvent().
// FIXME: SDL should do this internally
SDL_LockMutex(s_EventMutex);
SDL_CondWaitTimeout(s_EventCond, s_EventMutex, 1);
SDL_UnlockMutex(s_EventMutex);
continue;
}
}
void SDLHelper::pushEvent(SDL_Event* event)
{
initializeIfNeeded();
SDL_PushEvent(event);
// Immediately wake up the other waiting thread
SDL_LockMutex(s_EventMutex);
SDL_CondSignal(s_EventCond);
SDL_UnlockMutex(s_EventMutex);
}

16
app/streaming/sdlhelper.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <SDL.h>
class SDLHelper
{
public:
static void waitEvent(SDL_Event* event);
static void pushEvent(SDL_Event* event);
private:
static void initializeIfNeeded();
static SDL_cond* s_EventCond;
static SDL_mutex* s_EventMutex;
};

View File

@ -1,6 +1,7 @@
#include "session.h"
#include "settings/streamingpreferences.h"
#include "streaming/streamutils.h"
#include "streaming/sdlhelper.h"
#include <Limelight.h>
#include <SDL.h>
@ -981,14 +982,8 @@ void Session::exec(int displayOriginX, int displayOriginY)
// because we want to suspend all Qt processing until the stream is over.
SDL_Event event;
for (;;) {
// We explicitly use SDL_PollEvent() and SDL_Delay() because
// SDL_WaitEvent() has an internal SDL_Delay(10) inside which
// blocks this thread too long for high polling rate mice and high
// refresh rate displays.
if (!SDL_PollEvent(&event)) {
SDL_Delay(1);
continue;
}
SDLHelper::waitEvent(&event);
switch (event.type) {
case SDL_QUIT:
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,

View File

@ -3,6 +3,7 @@
#include <Limelight.h>
#include <SDL.h>
#include "settings/streamingpreferences.h"
#include "streaming/sdlhelper.h"
#define SDL_CODE_FRAME_READY 0
@ -53,6 +54,6 @@ public:
event.user.data1 = data1;
event.user.data2 = data2;
SDL_PushEvent(&event);
SDLHelper::pushEvent(&event);
}
};