]> git.vomp.tv Git - vompclient.git/commitdiff
OsdOpenVG: Switch to std::thread
authorChris Tallon <chris@vomp.tv>
Wed, 20 May 2020 20:10:00 +0000 (21:10 +0100)
committerChris Tallon <chris@vomp.tv>
Wed, 20 May 2020 20:10:00 +0000 (21:10 +0100)
osdopenvg.cc
osdopenvg.h

index d21e78c68bda2d4f2e9a3a13e41d8a9fee5568b3..abf94b80d0b17d5145163c31e1fcb80c059e9967 100644 (file)
@@ -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<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)
@@ -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;
 
index 87c074ac957231d0dc9ea6d1822ca90e071cd811..94b220789652ea322efbb9d8272442b81159fdf9 100644 (file)
@@ -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<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 */
 
@@ -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