From 4a0af3baea9256e0ffa19c3b6bb911b41e2067f7 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Wed, 20 May 2020 21:10:00 +0100 Subject: [PATCH] OsdOpenVG: Switch to std::thread --- osdopenvg.cc | 101 +++++++++++++++++++++++++++++++-------------------- osdopenvg.h | 15 ++++---- 2 files changed, 69 insertions(+), 47 deletions(-) diff --git a/osdopenvg.cc b/osdopenvg.cc index d21e78c..abf94b8 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -297,7 +297,18 @@ int OsdOpenVG::init() return 0; }*/ - threadStart(); + + renderThreadMutex.lock(); // start-protect + renderThreadReq = 0; + renderThread = std::thread( [this] + { + renderThreadMutex.lock(); + renderThreadMutex.unlock(); + renderLoop(); + }); + renderThreadMutex.unlock(); + + taskmutex.unlock(); vgmutex.unlock(); @@ -309,9 +320,20 @@ int OsdOpenVG::init() return 1; } +void OsdOpenVG::renderThreadStop() +{ + Log::getInstance()->log("OSDOpenVG", Log::WARN, "renderThreadStop"); + + renderThreadMutex.lock(); + renderThreadReq = 2; // req-stop + renderThreadCond.notify_one(); // in case renderLoop is in cond_wait + renderThreadMutex.unlock(); + renderThread.join(); +} + int OsdOpenVG::stopUpdate() { - threadStop(); + renderThreadStop(); processOpenVGCommands(); return 1; } @@ -329,7 +351,7 @@ int OsdOpenVG::shutdown() initted = false; Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1"); - threadStop(); + renderThreadStop(); Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1a"); //(((VideoOMX*)Video::getInstance())->shutdownUsingOSDObjects()); @@ -390,7 +412,7 @@ int OsdOpenVG::shutdown() return 1; } -void OsdOpenVG::threadMethod() +void OsdOpenVG::renderLoop() { // We have to claim the egl context for this thread Log::getInstance()->log("OSD", Log::NOTICE, "Entering drawing thread"); @@ -407,64 +429,61 @@ void OsdOpenVG::threadMethod() return; } + std::unique_lock ul(renderThreadMutex, std::defer_lock); int ts; while (true) { ts = 1; - if (initted) - { - long long time1 = getTimeMS(); + long long time1 = getTimeMS(); - if ((time1 - lastrendertime) > 200) //5 fps for OSD updates are enough, avoids tearing - { - #if DEV - dumpStyles(); - #endif + if ((time1 - lastrendertime) > 200) //5 fps for OSD updates are enough, avoids tearing + { + #if DEV + dumpStyles(); + #endif - InternalRendering(); - lastrendertime = getTimeMS(); + InternalRendering(); + lastrendertime = getTimeMS(); - ts = 10; - } - else - { - ts = time1 - lastrendertime; - } - - if (processOpenVGCommands()) ts = 0; + ts = 10; } + else + { + ts = time1 - lastrendertime; + } + + if (processOpenVGCommands()) ts = 0; - if (!threadIsActive()) + ul.lock(); + if (renderThreadReq == 2) { if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE) - { Log::getInstance()->log("OSD", Log::WARN, "Making egl Current out thread failed"); - } - - threadCheckExit(); + ul.unlock(); + return; } if (ts != 0) { - struct timespec target_time; - clock_gettime(CLOCK_REALTIME, &target_time); - target_time.tv_nsec += 1000000LL * ts; + renderThreadCond.wait_for(ul, std::chrono::milliseconds(ts), [this]{ return renderThreadReq != 0; }); - if (target_time.tv_nsec > 999999999) + if (renderThreadReq == 2) { - target_time.tv_nsec -= 1000000000L; - target_time.tv_sec += 1; + if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE) + Log::getInstance()->log("OSD", Log::WARN, "Making egl Current out thread failed"); + ul.unlock(); + return; } - threadLock(); - threadWaitForSignalTimed(&target_time); - threadUnlock(); + // Either timeout or renderThreadReq == 1 - go around + + renderThreadReq = 0; } - } - eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + ul.unlock(); + } } UINT OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm, bool wait) @@ -475,7 +494,11 @@ UINT OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm, bool wait) vgcommands.push_back(comm); ul.unlock(); - threadSignal(); // signal renderLoop + // signal renderLoop to go-around + renderThreadMutex.lock(); + if (renderThreadReq == 0) renderThreadReq = 1; + renderThreadCond.notify_one(); + renderThreadMutex.unlock(); if (!wait) return 0; diff --git a/osdopenvg.h b/osdopenvg.h index 87c074a..94b2207 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -34,7 +34,6 @@ #include "defines.h" #include "osdvector.h" #include "log.h" -#include "threadp.h" #include "videoomx.h" #include "staticartwork.h" #ifdef PICTURE_DECODER_OMX @@ -76,7 +75,7 @@ struct OpenVGCommand struct OpenVGResponse* response{}; // If !NULL, a thread is waiting }; -class OsdOpenVG : public OsdVector, public Thread_TYPE +class OsdOpenVG : public OsdVector #ifdef PICTURE_DECODER_OMX , public EGLPictureCreator #endif @@ -152,7 +151,12 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE unsigned int loadTTchar(cTeletextChar c); std::map tt_font_chars; - void threadMethod(); + std::thread renderThread; + std::mutex renderThreadMutex; // used for start-protect, go-around signal, quit signal + std::condition_variable renderThreadCond; + int renderThreadReq; // 1 - do update, 2 - stop + void renderLoop(); + void renderThreadStop(); /* BCM specific */ @@ -179,11 +183,6 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE #ifdef PICTURE_DECODER_OMX ImageOMX* imageomx; #endif - - // future - //std::thread renderThread; - //std::mutex threadStartProtect; - }; #endif -- 2.39.2