return 0;
}*/
- threadStart();
+
+ renderThreadMutex.lock(); // start-protect
+ renderThreadReq = 0;
+ renderThread = std::thread( [this]
+ {
+ renderThreadMutex.lock();
+ renderThreadMutex.unlock();
+ renderLoop();
+ });
+ renderThreadMutex.unlock();
+
+
taskmutex.unlock();
vgmutex.unlock();
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;
}
initted = false;
Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1");
- threadStop();
+ renderThreadStop();
Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1a");
//(((VideoOMX*)Video::getInstance())->shutdownUsingOSDObjects());
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");
return;
}
+ std::unique_lock<std::mutex> 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)
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;
#include "defines.h"
#include "osdvector.h"
#include "log.h"
-#include "threadp.h"
#include "videoomx.h"
#include "staticartwork.h"
#ifdef PICTURE_DECODER_OMX
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
unsigned int loadTTchar(cTeletextChar c);
std::map<unsigned int, int> 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 */
#ifdef PICTURE_DECODER_OMX
ImageOMX* imageomx;
#endif
-
- // future
- //std::thread renderThread;
- //std::mutex threadStartProtect;
-
};
#endif