]> git.vomp.tv Git - vompclient.git/commitdiff
Various performance optimization in the vector based osd, especially in text rendering
authorMarten Richter <marten.richter@freenet.de>
Sun, 26 Oct 2014 17:17:56 +0000 (18:17 +0100)
committerMarten Richter <marten.richter@freenet.de>
Sun, 26 Oct 2014 17:17:56 +0000 (18:17 +0100)
21 files changed:
boxstack.cc
boxx.cc
boxx.h
colour.h
demuxerts.cc
mutex.cc
mutex.h
osdopenvg.cc
osdopenvg.h
osdvector.cc
osdvector.h
region.cc
region.h
surface.cc
surface.h
surfacevector.cc
surfacevector.h
tbboxx.cc
tvmedia.cc
tvmedia.h
vepg.cc

index cf7890a030fb597095d914ad6f7a6693877ef4e2..b8cfee5a9c10038231c5baf6ecd34e98526ac9fd 100644 (file)
@@ -65,7 +65,9 @@ int BoxStack::shutdown()
 
 int BoxStack::addVideoDisplay(Boxx* box,VideoDisplay vd)
 {
+         boxLock.Lock();
          videoStack.push(pair<Boxx*,VideoDisplay>(box,vd));
+         boxLock.Unlock();
          Video::getInstance()->setVideoDisplay(vd);
          return 1;
 }
@@ -84,13 +86,14 @@ int BoxStack::add(Boxx* v)
     return 0;
   }
   boxes[numBoxes++] = v;
+  boxLock.Unlock();
   VideoDisplay vd;
   if (v->getVideoDisplay(vd)) {
          Log::getInstance()->log("BoxStack", Log::DEBUG, "Add video display");
          addVideoDisplay(v,vd);
   }
 
-  boxLock.Unlock();
+
 
   Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for add");
   
diff --git a/boxx.cc b/boxx.cc
index fd697bc349f592906d3f6d3eec297689316920a0..0e2687f848cd8519f64b576630b27671c33cb943 100644 (file)
--- a/boxx.cc
+++ b/boxx.cc
@@ -57,7 +57,7 @@ Boxx::~Boxx()
   numBoxxes--;
   Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes);
 }
-
+#include <typeinfo>
 void Boxx::draw()
 {
   //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p", this, surface);
@@ -69,8 +69,9 @@ void Boxx::draw()
   for (j = children.begin(); j != children.end(); j++)
   {
     currentBoxx = *j;
-   // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d", count,currentBoxx);
+   //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d %s", count,currentBoxx,typeid(*currentBoxx).name());
     if (currentBoxx->getVisible()) currentBoxx->draw();
+   //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw child %d %d end", count,currentBoxx);
    // count++;
   }  
  // Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p End", this, surface);
@@ -113,16 +114,18 @@ void Boxx::remove(Boxx* oldChild)
   Log::getInstance()->log("Boxx", Log::ERR, "Remove child box called, child %p not found", oldChild);
 }
 
-bool Boxx::overlapsVisibleChilds(Region & r)
+void Boxx::removeVisibleChilds(Region & r)
 {
        for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
-         {
-           if ((*i)->getVisible() && r.intersects((*i)->getRegionR()))
-           {
-             return true;
-           }
-         }
-       return false;
+       {
+               if ((*i)->getVisible())
+               {
+                       Region temp=(*i)->getRegionR();
+                       if (r.intersects(temp)) {
+                               r=r.subtract(temp);
+                       }
+               }
+       }
 }
 
 void Boxx::setParent(Boxx* newParent)
@@ -282,10 +285,10 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig
 {
   char line[256];
   int lineHeight = getFontHeight() + paraVSpace;
-
   float lineWidth;
   float thisCharWidth;
   int textPos;
+  int textLength;
   int linePos;
   int ypos;
   int printLine;
@@ -294,23 +297,49 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig
   int drawLinePos=-skiplines;
 
   textPos = 0;
+  textLength = strlen(text);
   ypos = y;
   Region tester;
-  tester.h = lineHeight;
+
 
   bool haschildren = true;
   if ( children.size() == 0) haschildren = false;
+  bool mchar=false;
+  Osd *osd=Osd::getInstance();
+  if (osd->charSet()!=1) mchar=true;
+  OsdVector *osdv=dynamic_cast<OsdVector*>(osd);
+  float *charwidtharray=NULL;
+  if (osdv) charwidtharray=osdv->getCharWidthArray();
+
+  mbstate_t state;
+  memset((void*)&state,0,sizeof(state));
 
   while(1)
   {
     linePos = 0;
     lineWidth = 0;
+    // tester reinit
+    tester.h = lineHeight;
     tester.y=ypos;
+    tester.x = x;
+    tester.w = area.w - (2 * paraMargin);
+
+    if (haschildren) removeVisibleChilds(tester);
+
     while(1)
     {
       printLine = 0;
-      UINT cur_length = 1;
-      wchar_t cur_char = getWChar(text + textPos, &cur_length);
+      int cur_length = 1;
+      wchar_t cur_char;
+      if (*(text + textPos) == '\0') break;
+      if (mchar) {
+         cur_length = mbrtowc(&cur_char, text + textPos, textLength-textPos, &state);
+         if (cur_length <= 0){
+                 cur_char='?';
+                 cur_length=1;
+         }
+      } else cur_char= *(text + textPos);
+
 
       if (cur_char == '\0') break;
 
@@ -320,12 +349,16 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig
         printLine = 1;
         break;
       }
-      thisCharWidth = charWidth(cur_char);
-      tester.x = lineWidth + x;
-      tester.w = thisCharWidth + 10;
+      if (charwidtharray) {
+         thisCharWidth=charwidtharray[cur_char & 0xFF];
+         if (cur_char && 0xFFFFFF00) thisCharWidth=osdv->getCharWidth(cur_char);
+      } else  thisCharWidth = charWidth(cur_char);
+
+
+
 
-      if ((lineWidth + thisCharWidth + x) > (int)(area.w - (2 * paraMargin))
-                 || (haschildren && overlapsVisibleChilds(tester)))
+
+      if ((lineWidth + thisCharWidth + x) > tester.w)
       {
         // this character would break the right margin
         if (cur_char == ' ')
@@ -340,7 +373,13 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig
           while ((cur_char != ' ') && (linePos >= 0))
           {
             textPos -= cur_length;
-            cur_char = getWChar(text + textPos, &cur_length);
+            if (mchar) {
+                 cur_length = mbrtowc(&cur_char, text + textPos, textLength-textPos, &state);
+                 if (cur_length <= 0){
+                       cur_char='?';
+                       cur_length=1;
+                 }
+            } else cur_char= *(text + textPos);
             linePos--;
           }
           // Now take the space we just found
@@ -348,7 +387,7 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig
           break;
         }
       }
-      for (UINT n = 0; n < cur_length; n++) line[linePos++] = text[textPos + n];
+      for (int n = 0; n < cur_length; n++) line[linePos++] = text[textPos + n];
       lineWidth += thisCharWidth;
       textPos += cur_length;
     }
@@ -527,12 +566,6 @@ float Boxx::charWidth(wchar_t c)
   else return 16.; //?
 }
 
-wchar_t Boxx::getWChar(const char* str, UINT *length)
-{
-  if (parent) return parent->getWChar(str, length);
-  else  if (surface) return surface->getWChar(str, length);
-  else return '?'; //?
-}
 
 Surface* Boxx::getSurface()
 {
diff --git a/boxx.h b/boxx.h
index 5cf60efc1e18c406bb7ac4a5db10efe5a63a335d..e6dbce1f0d883d42aa0b804b5cb177869647307a 100644 (file)
--- a/boxx.h
+++ b/boxx.h
@@ -126,7 +126,6 @@ class Boxx
     void endFastDraw();
 
     float charWidth(wchar_t c);
-    wchar_t getWChar(const char* str, unsigned int *length);
 
     void add(Boxx*); // a boxx has a set of child boxxs
     void remove(Boxx*);
@@ -152,7 +151,7 @@ class Boxx
 
     void setParent(Boxx*);    
     void blt(Region& r);
-    bool overlapsVisibleChilds(Region & r);
+    void removeVisibleChilds(Region & r);
 
     static const int paraMargin = 10;
     UINT paraVSpace;
index 746b3c10470fc13c1f4ae1e70a178ea87ad085cd..b99b5ebcf5abcbdc4a6c2fb8482f7f0d7b83ab1b 100644 (file)
--- a/colour.h
+++ b/colour.h
@@ -83,6 +83,15 @@ public:
                ft=Color;ct=Global;
        }
 
+       DrawStyle(const Colour &c)
+       {
+               red = c.red;
+               green = c.green;
+               blue = c.blue;
+               alpha = c.alpha;
+               ft=Color;ct=Global;
+       }
+
        enum FillType {
                        Color,
                        GradientLinear,
@@ -128,6 +137,67 @@ public:
 
 };
 
+#define COMPARE_TEST(x) if (rhs.x!=lhs.x) { \
+                                                       return rhs.x < lhs.x; \
+                                               }
+
+inline bool operator<(const DrawStyle& rhs, const DrawStyle& lhs)
+{
+       COMPARE_TEST(rgba())
+       COMPARE_TEST(ft)
+
+       if (rhs.ft==DrawStyle::Color) return false;
+
+       COMPARE_TEST(num_colors)
+       COMPARE_TEST(x1)
+       COMPARE_TEST(x2)
+       COMPARE_TEST(y1)
+       COMPARE_TEST(y2)
+       if (rhs.ft==DrawStyle::GradientRadial) COMPARE_TEST(r)
+
+
+       for (int i=0;i<lhs.num_colors; i++) {
+               COMPARE_TEST(grad_col[i].rgba())
+               if (i>0) COMPARE_TEST(grad_pos[i-1])
+       }
+       COMPARE_TEST(ct)
+
+       return false;
+}
+
+
+#undef COMPARE_TEST
+
+#define COMPARE_TEST(x) if (rhs.x!=lhs.x) return true;
+
+
+inline bool operator!=(const DrawStyle& rhs, const DrawStyle& lhs)
+{
+       COMPARE_TEST(rgba())
+       COMPARE_TEST(ft)
+
+       if (rhs.ft==DrawStyle::Color) return false;
+
+       COMPARE_TEST(num_colors)
+       COMPARE_TEST(x1)
+       COMPARE_TEST(x2)
+       COMPARE_TEST(y1)
+       COMPARE_TEST(y2)
+       if (rhs.ft==DrawStyle::GradientRadial) COMPARE_TEST(r)
+
+
+       for (int i=0;i<lhs.num_colors; i++) {
+               COMPARE_TEST(grad_col[i].rgba())
+               if (i>0) COMPARE_TEST(grad_pos[i-1])
+       }
+       COMPARE_TEST(ct)
+
+       return false;
+}
+
+#undef COMPARE_TEST
+
+
 class SkinFactory {
 public:
        static int getNumberofSkins();
index c5e086ac20d69e43c63f78925160fd6c17e49918..f11ba51d441601ea91470eafae5b1dea79b73ca1 100644 (file)
@@ -574,7 +574,7 @@ int DemuxerTS::processTS(UCHAR* buf)
                        setAID(channelinfo.dpids[selected].pid,1,channelinfo.dpids[selected].type,false);
                        Audio::getInstance()->setStreamType(Audio::MPEG2_PES);
                } else {
-                       setAID(channelinfo.dpids[selected].pid,0,channelinfo.apids[selected].type,false);
+                       setAID(channelinfo.apids[selected].pid,0,channelinfo.apids[selected].type,false);
                        Audio::getInstance()->setStreamType(Audio::MPEG2_PES);
                }
             }
index 1ba790a49d2320a51ba752cab38c6f3ed6d66ed1..7b36255171c89c0b7e80ffd3e34eb8b633366c0a 100644 (file)
--- a/mutex.cc
+++ b/mutex.cc
 */
 #include "mutex.h"
 
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
 Mutex::Mutex() {
 #ifndef WIN32
        pthread_mutex_init(&my_mutex, NULL);
 #else
         my_mutex=CreateMutex(NULL,FALSE,NULL);
 #endif
+        my_cur_thread=0;
+        num_locks=0;
 }
 
 Mutex::~Mutex() {
@@ -34,18 +40,40 @@ Mutex::~Mutex() {
 }
 
 void Mutex::Lock() {
+       if (num_locks> 0) {
+#ifndef WIN32
+               if (my_cur_thread==(pid_t) syscall(SYS_gettid)) {
+#else
+               if (my_cur_thread==GetCurrentThreadId()) {
+#endif
+                       num_locks++;
+                       return;
+               }
+       }
 #ifndef WIN32
   pthread_mutex_lock(&my_mutex);
+  my_cur_thread=syscall(SYS_gettid);
 #else
    WaitForSingleObject(my_mutex, INFINITE );
+   my_cur_thread=GetCurrentThreadId();
 #endif
+   num_locks++;
+
 }
 
 void Mutex::Unlock() {
 #ifndef WIN32
-  pthread_mutex_unlock(&my_mutex);
+       if (my_cur_thread==syscall(SYS_gettid)) num_locks--;
+#else
+       if (my_cur_thread==GetCurrentThreadId()) num_locks--;
+#endif
+       if (num_locks==0) {
+               my_cur_thread=0;
+#ifndef WIN32
+               pthread_mutex_unlock(&my_mutex);
 #else
-   ReleaseMutex(my_mutex);
+               ReleaseMutex(my_mutex);
 #endif
+       }
 }
 
diff --git a/mutex.h b/mutex.h
index 21b04b7ab8d8f5c8ccfcd66fd02ad826eaefba5f..bab9f210414c88c7f05f8b504cbc71625475dfd4 100644 (file)
--- a/mutex.h
+++ b/mutex.h
@@ -23,6 +23,7 @@
 
 #ifndef WIN32
 #include <pthread.h>
+#include <sys/types.h>
 #else
 #include <winsock2.h>
 #include <windows.h>
@@ -40,8 +41,11 @@ public:
 protected:
 #ifndef WIN32
         pthread_mutex_t my_mutex;
+        pid_t my_cur_thread;
 #else
        HANDLE my_mutex;
+       DWORD my_cur_thread;
 #endif
+       int num_locks;
 };
 #endif
index 45cab2153874922b26a2aef84224cc63a7294a9d..e59fb7912738e3a7d96ecd1a2b87be0af15ea00f 100644 (file)
@@ -619,6 +619,7 @@ float OsdOpenVG::getFontHeight()
 }
 float OsdOpenVG::getCharWidth(wchar_t c)
 {
+       if (c<256) return byte_char_width[c];
        unsigned int glyph_index=FT_Get_Char_Index(ft_face,c);
        return font_exp_x[glyph_index];
 }
@@ -863,6 +864,10 @@ int  OsdOpenVG::loadFont(bool newfont)
                }
                cur_char = FT_Get_Next_Char(ft_face,cur_char,&glyph);
        }
+       for (int i=0;i<256;i++) {
+               unsigned int glyph_index=FT_Get_Char_Index(ft_face,i);
+               byte_char_width[i]=font_exp_x[glyph_index];
+       }
        return 1;
 }
 
@@ -1507,14 +1512,6 @@ unsigned int OsdOpenVG::createStyleRef(const DrawStyle &c)
        return putOpenVGCommand(comm,true);
 }
 
-unsigned int OsdOpenVG::createColorRef(const Colour &c)
-{
-       unsigned int col=c.rgba();
-       struct OpenVGCommand comm;
-       comm.task=OVGcreateColorRef;
-       comm.param1=col<<8 | (col &0xff000000)>>24;
-       comm.data=&c;
-       return putOpenVGCommand(comm,true);
-}
+
 
 
index e0a07bd0566e5816c67f2b031ba21e2289a4ad30..efcb2eaf8fb16ee8394746c4dcf86b4dd8103551 100644 (file)
@@ -115,7 +115,6 @@ protected:
     void createPicture(struct PictureInfo& pict_inf);
     void destroyStyleRef(unsigned int index);
        unsigned int createStyleRef(const DrawStyle &c);
-       unsigned int createColorRef(const Colour &c);
        bool getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length);
 
        void drawSetTrans(SurfaceCommands & sc);
index aa872fb1376451b497953bbd383f47fc7cf26ef9..a05a70924c82b26cf1d376b2703e877211955657 100644 (file)
@@ -108,6 +108,11 @@ OsdVector::OsdVector()
        reader.addDecoder(new MagickDecoder(&reader));
 #endif
 
+       for (int i=0;i<256;i++) {
+               byte_char_width[i]=0.f;
+       }
+       styles_lastit_valid=styles_ref_lastit_valid=false;
+
 }
 
 OsdVector::~OsdVector()
@@ -168,6 +173,7 @@ int OsdVector::restore()
        list<SurfaceCommands>::iterator curdraw=scommands.begin();
        while (curdraw!=scommands.end()) {
                (*curdraw).commands.clear();
+               (*curdraw).commands.reserve(2048);
                curdraw++;
        }
        //also clear all handles, they are now invalid, no need to release them
@@ -176,6 +182,7 @@ int OsdVector::restore()
        //jpegs.clear();
        styles.clear();
        styles_ref.clear();
+       styles_lastit_valid=styles_ref_lastit_valid=false;
        palettepics.clear();
 
        tvmedias.clear();
@@ -219,8 +226,8 @@ void OsdVector::drawSurfaces()
        list<SurfaceCommands*>::iterator curdraw=todraw.begin();
        while (curdraw!=todraw.end()) {
                drawSetTrans(*(*curdraw));
-               list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
-               list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
+               std::vector<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
+               std::vector<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
                while (commands!=end) {
                        // update any images loaded in the mean time
                        if ((*commands).instr==DrawImageLoading) {
@@ -246,7 +253,7 @@ void OsdVector::drawSurfaces()
 }
 
 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
-                       list<SVGCommand>& commands)
+                       std::vector<SVGCommand>& commands)
 {
        surfaces_mutex.Lock();
        //First determine it is already in our system
@@ -270,7 +277,7 @@ void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,flo
                itty=scommands.insert(itty,new_sc);
        }
        // update any images loaded in the mean time
-       list<SVGCommand>::iterator ilitty=commands.begin();
+       std::vector<SVGCommand>::iterator ilitty=commands.begin();
 
        while (ilitty!=commands.end())
        {
@@ -316,10 +323,10 @@ void OsdVector::removeSurface(const SurfaceVector *surf)
 
 }
 
-void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
+void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
 {
 
-       list<SVGCommand>::iterator sitty = commands.begin();
+       std::vector<SVGCommand>::iterator sitty = commands.begin();
        while (sitty != commands.end()) {
                removeStyleRef((*sitty).getRef());
                ImageIndex ii = (*sitty).getImageIndex();
@@ -330,9 +337,9 @@ void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
        }
 }
 
-void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )
+void OsdVector::referenceSVGCommand(std::vector<SVGCommand>& commands )
 {
-       list<SVGCommand>::iterator sitty=commands.begin();
+       std::vector<SVGCommand>::iterator sitty=commands.begin();
        while (sitty!=commands.end())
        {
                incStyleRef((*sitty).getRef());
@@ -475,7 +482,7 @@ void OsdVector::cleanupOrphanedRefs()
        }
 
 
-       map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
+       map<DrawStyle,unsigned int>::iterator sitty=styles.begin();
        while (sitty!=styles.end()) {
                map<unsigned int,int>::iterator curitty=styles_ref.find((*sitty).second);
                int count=(*curitty).second;
@@ -483,6 +490,7 @@ void OsdVector::cleanupOrphanedRefs()
                        unsigned int ref=(*curitty).first;
                        styles.erase(sitty++);
                        styles_ref.erase(curitty++);
+                       styles_lastit_valid=styles_ref_lastit_valid=false;
                        destroyStyleRef(ref);
 
                } else ++sitty;
@@ -504,75 +512,81 @@ int OsdVector::getImageRef(ImageIndex index)
 
 void OsdVector::incStyleRef(unsigned int index)
 {
-       if (styles_ref.find(index)==styles_ref.end()) {
-               styles_ref[index]=1;
+       if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
+               styles_ref_lastit_valid=false;
+               styles_ref_lastit=styles_ref.find(index);
+       }
+       if (styles_ref_lastit==styles_ref.end()) {
+               styles_ref_lastit=styles_ref.insert(std::pair<unsigned int,int>(index,1)).first;
        } else {
-               styles_ref[index]++;
+               (*styles_ref_lastit).second++;
        }
+       styles_ref_lastit_valid=true;
 }
 
 void OsdVector::removeStyleRef(unsigned int index)
 {
-       styles_ref[index]--;
+       if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
+               styles_ref_lastit_valid=false;
+               styles_ref_lastit=styles_ref.find(index);
+       }
+       if (styles_ref_lastit!=styles_ref.end())  {
+               styles_ref_lastit_valid=true;
+               (*styles_ref_lastit).second--;
+       }
 }
 
 unsigned int OsdVector::getStyleRef(const DrawStyle &c)
 {
        surfaces_mutex.Lock();
        unsigned int style_handle=0;
-       if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
+       if (!styles_lastit_valid || (*styles_lastit).first!=c) {
+               styles_lastit_valid=false;
+               styles_lastit=styles.find(c);
+       }
+
+       if (styles_lastit==styles.end())
        {
                surfaces_mutex.Unlock();
                style_handle=createStyleRef(c);
                surfaces_mutex.Lock();
-               styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=style_handle;
+               styles_lastit=styles.insert(std::pair<DrawStyle,unsigned int>(c,style_handle)).first;
        } else {
-               style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
+
+               style_handle=(*styles_lastit).second;
                //Now check if the handle is valid
-               if (styles_ref.find(style_handle)==styles_ref.end()) {
-                       //invalid handle recreate
-                       surfaces_mutex.Unlock();
-                       style_handle=createStyleRef(c);
-                       surfaces_mutex.Lock();
-                       styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=style_handle;
+               if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=style_handle) {
+                       styles_ref_lastit_valid=false;
+                       styles_ref_lastit=styles_ref.find(style_handle);
                }
-       }
-       incStyleRef(style_handle);
-       surfaces_mutex.Unlock();
-       return style_handle;
-}
 
-unsigned int OsdVector::getColorRef(const Colour &c)
-{
-       surfaces_mutex.Lock();
-       unsigned int style_handle=0;
-       if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
-       {
-               surfaces_mutex.Unlock();
-               style_handle=createColorRef(c);
-               surfaces_mutex.Lock();
-               styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=style_handle;
-       } else {
-               style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
-               if (styles_ref.find(style_handle)==styles_ref.end()) {
+               if (styles_ref_lastit==styles_ref.end()) {
                        //invalid handle recreate
                        surfaces_mutex.Unlock();
-                       style_handle=createColorRef(c);
+                       style_handle=createStyleRef(c);
                        surfaces_mutex.Lock();
-                       styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=style_handle;
-               }
+                       (*styles_lastit).second=style_handle;
+               } else styles_ref_lastit_valid=true;
        }
+       styles_lastit_valid=true;
        incStyleRef(style_handle);
        surfaces_mutex.Unlock();
        return style_handle;
 }
 
+
+
 int OsdVector::getStyleRef(unsigned int index)
 {
-       if (styles_ref.find(index)==styles_ref.end()) {
+       if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
+               styles_ref_lastit_valid=false;
+               styles_ref_lastit=styles_ref.find(index);
+       }
+       if (styles_ref_lastit==styles_ref.end()) {
                return -1;
        } else {
-               return styles_ref[index];
+               styles_ref_lastit_valid=true;
+               return (*styles_ref_lastit).second;
        }
 }
 
index 0daae43da6a9697413685cfd3685cad74978cde4..fe097e44d04d606f216c6c809f0bd2a9caaa48d6 100644 (file)
@@ -25,6 +25,7 @@
 #include "colour.h"
 #include <set>
 #include <list>
+#include <vector>
 #include <map>
 #include <queue>
 #include <string>
@@ -71,7 +72,7 @@ public:
                x=y=w=h=reference=0;
     };
 
-       static SVGCommand PaintPath(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
+       inline static SVGCommand PaintPath(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
        {
                SVGCommand nc;
                nc.instr=DrawPath;
@@ -84,7 +85,7 @@ public:
                return nc;
        };
 
-       static SVGCommand PaintImageLoading(LoadIndex load_in,float ix, float iy,float iw,float ih,unsigned int ref, Corner corner=TopLeft)
+       inline static SVGCommand PaintImageLoading(LoadIndex load_in,float ix, float iy,float iw,float ih,unsigned int ref, Corner corner=TopLeft)
        {
                SVGCommand nc;
                nc.instr=DrawImageLoading;
@@ -98,7 +99,7 @@ public:
                return nc;
        };
 
-       static SVGCommand PaintImage(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref, Corner corner=TopLeft)
+       inline static SVGCommand PaintImage(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref, Corner corner=TopLeft)
        {
                SVGCommand nc;
                nc.instr=DrawImage;
@@ -114,7 +115,7 @@ public:
 
 
 
-       static SVGCommand PaintTTchar(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
+       inline static SVGCommand PaintTTchar(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
        {
                SVGCommand nc;
                nc.instr=DrawTTchar;
@@ -127,7 +128,7 @@ public:
                nc.corner=TopLeft;
                return nc;
        };
-       static SVGCommand PaintClipping(float ix, float iy,float iw,float ih)
+       inline static SVGCommand PaintClipping(float ix, float iy,float iw,float ih)
        {
                SVGCommand nc;
                nc.instr=DrawClipping;
@@ -141,9 +142,8 @@ public:
        };
 
 
-       static SVGCommand PaintGlyph(float ix, float iy,wchar_t char_in,unsigned int ref)
+       inline static void PaintGlyph(SVGCommand& nc, float ix, float iy,wchar_t char_in,unsigned int ref)
        {
-               SVGCommand nc;
                nc.instr=DrawGlyph;
                nc.x=ix;
                nc.y=iy;
@@ -151,7 +151,6 @@ public:
                nc.h=0;
                nc.reference=ref;
                nc.target.textchar=char_in;
-               return nc;
        };
 
        bool Test(float tx,float ty,float tw, float th)
@@ -178,6 +177,7 @@ public:
        };
 
        SVGCommandInstr instr;
+       Corner corner;
        float x,y,w,h;
        unsigned int reference;
        union {
@@ -187,7 +187,7 @@ public:
                unsigned int ttchar;
                LoadIndex loadindex;
        } target;
-       Corner corner;
+
 
 };
 
@@ -196,7 +196,7 @@ class VDR_ResponsePacket;
 
 struct SurfaceCommands{
        const SurfaceVector* surf;
-       list<SVGCommand> commands;
+       vector<SVGCommand> commands;
        float x,y,w,h;
 };
 
@@ -220,11 +220,12 @@ class OsdVector : public Osd
        void Blank();
 
        void updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
-                       list<SVGCommand>& commands);
+                       std::vector<SVGCommand>& commands);
        void removeSurface(const SurfaceVector *surf);
 
        virtual float getFontHeight()=0;
        virtual float getCharWidth(wchar_t c)=0;
+       float *getCharWidthArray() {return byte_char_width;};
 
        //virtual ImageIndex getJpegRef(const char* fileName, int *width,int *height);
        virtual LoadIndex getTVMediaRef(TVMediaInfo& tvmedia,ImageIndex& image);
@@ -237,7 +238,6 @@ class OsdVector : public Osd
 
        void removeImageRef(const ImageIndex ref);
        void removeLoadIndexRef(const LoadIndex ref);
-       unsigned int getColorRef(const Colour &c); //internally this is the same as getStyleRef
        unsigned int getStyleRef(const DrawStyle &c);
        virtual void removeStyleRef(unsigned int ref);
        virtual void getScreenSize(int &width, int &height)=0;
@@ -380,15 +380,21 @@ protected:
 
 
        void incStyleRef(unsigned int index);
-       int getStyleRef(ImageIndex index);
+       int getStyleRef(unsigned int index);
        virtual void destroyStyleRef(unsigned int index)=0;
-       map<pair<Colour*,unsigned int>,unsigned int> styles;
+
+
+       map<DrawStyle,unsigned int> styles;
        map<unsigned int,int> styles_ref;
+       map<DrawStyle,unsigned int>::iterator styles_lastit;
+       bool styles_lastit_valid;
+       map<unsigned int,int>::iterator styles_ref_lastit;
+       bool styles_ref_lastit_valid;
+
        virtual unsigned int createStyleRef(const DrawStyle &c)=0;
-       virtual unsigned int createColorRef(const Colour &c)=0;
 
-       void dereferenceSVGCommand(list<SVGCommand>& commands );
-       void referenceSVGCommand(list<SVGCommand>& commands );
+       void dereferenceSVGCommand(std::vector<SVGCommand>& commands );
+       void referenceSVGCommand(std::vector<SVGCommand>& commands );
        void cleanupOrphanedRefs();
 
 
@@ -399,10 +405,12 @@ protected:
 
 
 
-       list<SurfaceCommands> scommands;
+       std::list<SurfaceCommands> scommands;
 
        Mutex surfaces_mutex;
 
+       float byte_char_width[256];
+
        void drawSurfaces();
 };
 
index c46944e69a1596d8b2869a56c9001fbace41ee5e..b556277244b40e718ef0ef43f8a741c62cc26338 100644 (file)
--- a/region.cc
+++ b/region.cc
@@ -41,18 +41,18 @@ Region Region::operator + (Region& other)
 }
     
     
-/*
+
 Region Region::subtract(Region& other)
 {
-  OK printf("This:           %i %i %i %i\n", x, y, w, h);
-  OK printf("Subtract this:  %i %i %i %i\n", other.x, other.y, other.w, other.h);
+  //OK printf("This:           %i %i %i %i\n", x, y, w, h);
+  //OK printf("Subtract this:  %i %i %i %i\n", other.x, other.y, other.w, other.h);
 
 
   Region s;
 
   if (x < other.x)
   {
-OK    printf("Case 1\n");
+//OK    printf("Case 1\n");
     s.x = x;
     s.y = y;
     s.w = other.x - x;
@@ -60,7 +60,7 @@ OK    printf("Case 1\n");
   }
   else if (x2() > other.x2())
   {
-OK    printf("Case 2\n");
+//OK    printf("Case 2\n");
     s.x = other.x2()+1;
     s.y = y;
     s.w = w - s.x;
@@ -68,7 +68,7 @@ OK    printf("Case 2\n");
   }
   else if (y < other.y)
   {
-OK    printf("Case 3\n");
+//OK    printf("Case 3\n");
     s.x = x;
     s.y = y;
     s.w = w;
@@ -76,7 +76,7 @@ OK    printf("Case 3\n");
   }
   else if (y2() > other.y2())
   {
-OK    printf("Case 4\n");
+//OK    printf("Case 4\n");
     s.x = x;
     s.y = other.y2()+1;
     s.w = w;
@@ -89,11 +89,11 @@ OK    printf("Case 4\n");
     s.w = 0;
     s.h = 0;
   }
-  OK printf("Result:         %i %i %i %i\n", s.x, s.y, s.w, s.h);
+  //OK printf("Result:         %i %i %i %i\n", s.x, s.y, s.w, s.h);
 
   return s;
 }
-*/
+
 
   //i.x = (x >= other.x ? x : other.x);
   //i.y = (y >= other.y ? y : other.y);
index ad231130760e161159d1d392558c249bf264d70d..2b191b17a0f35f340a96ed4018ac094208800eb4 100644 (file)
--- a/region.h
+++ b/region.h
@@ -9,7 +9,7 @@ class Region
   public:
     Region();
     bool overlappedBy(Region& doesthisOverlap);
-//    Region subtract(Region& other);
+    Region subtract(Region& other);
     Region operator + (Region& other);
     inline bool intersects(Region  test) {
        return  !((test.x+test.w) < x || (x + w) < test.x
index 390c237968b2e7a7f9c268697d72f3ce2399edd6..d28b178c30d9ac34ed2e3c7821462b7efbaed665 100644 (file)
@@ -180,12 +180,6 @@ int Surface::getFontHeight()
 }
 #endif
 
- wchar_t Surface::getWChar(const char* str, unsigned int *length)
- {
-        *length=1;
-        return *str;
- }
-
 //Moved from Teletext view in order to allow device depend optimizations
 
 Colour Surface::enumTeletextColorToCoulour(enumTeletextColor ttcol)
index 228cd421c25f6ac1dab2429a09e0b85f917ad207..bb3a6f9184f3f7e793a32326cb1eca1d4978625f 100644 (file)
--- a/surface.h
+++ b/surface.h
@@ -59,7 +59,6 @@ class Surface
     virtual ~Surface();
 
     static Surface* getScreen();
-    virtual wchar_t getWChar(const char* str, unsigned int *length);
 
 #ifdef GRADIENT_DRAWING
     virtual int getFontHeight()=0;
index af23530dff9f9769351bff031534123879489c7f..8167128a2a8c7f206aa38f79e87434e36f1909d5 100644 (file)
@@ -29,12 +29,13 @@ SurfaceVector::SurfaceVector(OsdVector* vosd)
 {
 
        osd=vosd;
+       commands.reserve(2048);
 }
 
 SurfaceVector::~SurfaceVector()
 {
        osd->removeSurface(this);
-       list<SVGCommand>::iterator itty=commands.begin();
+       vector<SVGCommand>::iterator itty=commands.begin();
        while (itty!=commands.end())
        {
                osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
@@ -59,32 +60,6 @@ float SurfaceVector::getCharWidth(wchar_t c)
        return osd->getCharWidth(c);
 }
 
-wchar_t SurfaceVector::getWChar(const char* str, unsigned int *length)
-{
-       int mlength=0;
-       int max_length=4;
-       wchar_t tempo[1];
-       size_t num_bytes=1;
-       if (str[0]=='\0') {
-               *length=1;
-               return '\0';
-       } else if (str[1]=='\0'){
-               max_length=2;
-       } else if (str[2]=='\0'){
-               max_length=3;
-       }
-       mbstate_t state;
-       memset((void*)&state,0,sizeof(state));
-       num_bytes=mbrtowc(tempo, str, max_length, &state);
-       if (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2))
-       {
-               *length=num_bytes;
-               return *tempo;
-       }
-       *length=1;
-       return '?';
-}
-
 
 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){
        return drawText(text, x, y, 0, c);
@@ -95,25 +70,37 @@ int SurfaceVector::drawText(const char* text, int x, int y, int width, const Dra
        float shift=0.;
        const char *run=text;
        mbstate_t state;
-       wchar_t tempo[1];
+       wchar_t tempo;
        size_t num_bytes=1;
        size_t length=strlen(text);
        memset((void*)&state,0,sizeof(state));
+
        command_mutex.Lock();
-       num_bytes=mbrtowc(tempo, run, length, &state);
+       num_bytes=mbrtowc(&tempo, run, length, &state);
+       unsigned int ref=osd->getStyleRef(c);
+       float *charwidtharray=osd->getCharWidthArray();
+
+       int commands_size=commands.size();
+       int chars=0;
+       commands.resize(commands_size+strlen(text));
+
        while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
        {
-               unsigned int ref=osd->getStyleRef(c);
-               commands.push_back(SVGCommand::PaintGlyph(x+shift,y,*tempo,ref));
-               shift+=osd->getCharWidth(*tempo);
+               SVGCommand::PaintGlyph(commands[commands_size+chars],x+shift,y,tempo,ref);
+               chars++;
+
+               float cur_shift=charwidtharray[tempo & 0xFF];
+               if (tempo && 0xFFFFFF00) cur_shift=osd->getCharWidth(tempo);
+               shift+=cur_shift;
                length -= num_bytes;
                run += num_bytes;
                if (shift>width && width >0) {
                        command_mutex.Unlock();
                        return 1;
                }
-               num_bytes=mbrtowc(tempo, run, length, &state);
+               num_bytes=mbrtowc(&tempo, run, length, &state);
        }
+       commands.resize(commands_size+chars);
        command_mutex.Unlock();
        return 1;
 
@@ -303,7 +290,9 @@ void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int hei
 int SurfaceVector::removeCommands(float x,float y,float width,float height)
 {
        // we iterate through all old commands in order to remove commands hidden by this rectangle
-       list<SVGCommand>::iterator itty=commands.begin();
+       vector<SVGCommand>::iterator itty=commands.begin();
+       vector<SVGCommand>::iterator remstart;
+       bool remove=false;
        while (itty!=commands.end())
        {
                if ((*itty).Test(x,y,width,height)  && (*itty).instr != DrawClipping) {
@@ -314,10 +303,20 @@ int SurfaceVector::removeCommands(float x,float y,float width,float height)
                        if (ii) osd->removeImageRef(ii);
                        LoadIndex li=(*itty).getLoadIndex();
                        if (li) osd->removeLoadIndexRef(li);
-                       itty=commands.erase(itty);
+                       if (!remove)  {
+                               remstart=itty;
+                               remove=true;
+                       }
                } else {
-                       itty++;
+                       if (remove) {
+                               itty=commands.erase(remstart,itty);
+                               remove=false;
+                       }
                }
+               itty++;
+       }
+       if (remove) {
+               itty=commands.erase(remstart,itty);
        }
        return 1;
 
@@ -345,7 +344,7 @@ void SurfaceVector::endFastDraw() {
 void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
 {
        command_mutex.Lock();
-       list<SVGCommand>::iterator itty=commands.begin();
+       vector<SVGCommand>::iterator itty=commands.begin();
        while (itty!=commands.end())
        {
                if ((*itty).TTTest(ox,oy,x,y) ) {
index fb31b17b9ccd63d871665bc6989927a775507769..71c07bcf1140a3ae0dbe48c0a5839534494acb17 100644 (file)
@@ -24,7 +24,7 @@
 #include "surface.h"
 #include "osdvector.h"
 
-#include <list>
+#include <vector>
 
 
 class SurfaceVector : public Surface
@@ -35,7 +35,6 @@ class SurfaceVector : public Surface
 
     int getFontHeight();
     float getCharWidth(wchar_t c);
-    wchar_t getWChar(const char* str, unsigned int *length);
 
     int drawText(const char* text, int x, int y, const DrawStyle& c);
     int drawText(const char* text, int x, int y, int width, const DrawStyle& c);
@@ -76,7 +75,7 @@ class SurfaceVector : public Surface
 
     int removeCommands(float x,float y,float width,float height);
 
-    list<SVGCommand> commands;
+    std::vector<SVGCommand> commands;
     int swidth, sheight;
     Mutex command_mutex;
     OsdVector* osd;
index 58ce630ce7533e63de2dff3d55a21706bc73c2fa..4ecd3240ef9b5d4d535a6ac8e84d5dc689db4762 100644 (file)
--- a/tbboxx.cc
+++ b/tbboxx.cc
@@ -48,7 +48,7 @@ void TBBoxx::setTitleText(const char* takeText, int width)
 void TBBoxx::draw()
 {
   //Log::getInstance()->log("TBBoxx", Log::DEBUG, "Draw: %d",this);
-  
+
   fillColour(DrawStyle::VIEWBACKGROUND);
 
   if (borderOn)
index feb2577bac74f40b9cf5b89bce2f446eff16f35e..fd6968ecf376a7d9116f39ae32a6351768b2f16f 100644 (file)
@@ -95,49 +95,4 @@ void TVMediaInfo::setChannelLogo(int channel)
        primary_id=channel;
 }
 
-bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
-{
-       if (rhs.type==lhs.type) {
-               if (rhs.primary_id==lhs.primary_id) {
-                       if (rhs.static_fallback==lhs.static_fallback) {
-                               if (rhs.secondary_id==lhs.secondary_id) {
-                                       if (rhs.type_pict==lhs.type_pict) {
-                                               if (rhs.container==lhs.container) {
-                                                       if (rhs.primary_name== lhs.primary_name) {
-                                                               return rhs.container_member < lhs.container_member;
-                                                       } else {
-                                                               return rhs.primary_name < lhs.primary_name;
-                                                       }
-                                               } else {
-                                                       return rhs.container<lhs.container;
-                                               }
-
-
-                                       } else {
-                                               return rhs.type_pict<lhs.type_pict;
-                                       }
-
-                               } else {
-                                       return rhs.secondary_id<lhs.secondary_id;
-                               }
-                       } else {
-                               return rhs.static_fallback<lhs.static_fallback;
-                       }
-
-               } else {
-                       return rhs.primary_id<lhs.primary_id;
-               }
-
-
-       } else {
-               return rhs.type < lhs.type;
-       }
-}
 
-bool operator==(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
-{
-       return (rhs.type==lhs.type)  && (rhs.primary_id==lhs.primary_id) && (rhs.static_fallback==lhs.static_fallback)  &&
-            (rhs.secondary_id==lhs.secondary_id) && (rhs.type_pict==lhs.type_pict) &&
-               (rhs.container==lhs.container)  && (rhs.primary_name== lhs.primary_name)
-                                               && (rhs.container_member == lhs.container_member);
-}
index 67c02e62c01ea43e492b8c74d0150a1ff72a775b..da5ad85dec55d1dc549b151e333406ce14c189ea 100644 (file)
--- a/tvmedia.h
+++ b/tvmedia.h
@@ -86,4 +86,52 @@ struct Actor
 
 typedef std::vector<Actor> Actors;
 
+
+inline bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
+{
+       if (rhs.type==lhs.type) {
+               if (rhs.primary_id==lhs.primary_id) {
+                       if (rhs.static_fallback==lhs.static_fallback) {
+                               if (rhs.secondary_id==lhs.secondary_id) {
+                                       if (rhs.type_pict==lhs.type_pict) {
+                                               if (rhs.container==lhs.container) {
+                                                       if (rhs.primary_name== lhs.primary_name) {
+                                                               return rhs.container_member < lhs.container_member;
+                                                       } else {
+                                                               return rhs.primary_name < lhs.primary_name;
+                                                       }
+                                               } else {
+                                                       return rhs.container<lhs.container;
+                                               }
+
+
+                                       } else {
+                                               return rhs.type_pict<lhs.type_pict;
+                                       }
+
+                               } else {
+                                       return rhs.secondary_id<lhs.secondary_id;
+                               }
+                       } else {
+                               return rhs.static_fallback<lhs.static_fallback;
+                       }
+
+               } else {
+                       return rhs.primary_id<lhs.primary_id;
+               }
+
+
+       } else {
+               return rhs.type < lhs.type;
+       }
+}
+
+inline bool operator==(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
+{
+       return (rhs.type==lhs.type)  && (rhs.primary_id==lhs.primary_id) && (rhs.static_fallback==lhs.static_fallback)  &&
+            (rhs.secondary_id==lhs.secondary_id) && (rhs.type_pict==lhs.type_pict) &&
+               (rhs.container==lhs.container)  && (rhs.primary_name== lhs.primary_name)
+                                               && (rhs.container_member == lhs.container_member);
+}
+
 #endif
diff --git a/vepg.cc b/vepg.cc
index 76662f29b79c4b1a1574ffb445455d68e6d1b0c5..32cd413bb2b3f0dd1d7318726c1cb7b08e899367 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -720,10 +720,21 @@ void VEpg::paintCell(Event* event, int yOffset, const DrawStyle& bg, const DrawS
   float textWidth = 0;
   unsigned int cur_length=1;
   unsigned int text_max=strlen(tt);
+  bool mchar=false;
+  if (Osd::getInstance()->charSet()!=1) mchar=true;
+  mbstate_t state;
+  memset((void*)&state,0,sizeof(state));
+
   UINT textPos;
   for (textPos = 0; textPos <text_max; textPos+=cur_length)
   {
-       wchar_t cur_char=getWChar(tt+textPos,&cur_length);
+       wchar_t cur_char;
+       if (mchar) {
+               cur_length = mbrtowc(&cur_char, tt + textPos, text_max-textPos, &state);
+               if (cur_length <= 0){
+                       break;
+               }
+       } else cur_char= *(tt+textPos);
     float thisCharWidth = charWidth(cur_char);
     if (textWidth + thisCharWidth > w) // text will not fit in cell
     {