From dbf4b12c63708aed7d1a2733efe5e26a9624d995 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 26 Oct 2014 18:17:56 +0100 Subject: [PATCH] Various performance optimization in the vector based osd, especially in text rendering --- boxstack.cc | 5 ++- boxx.cc | 87 +++++++++++++++++++++++++++------------ boxx.h | 3 +- colour.h | 70 +++++++++++++++++++++++++++++++ demuxerts.cc | 2 +- mutex.cc | 32 ++++++++++++++- mutex.h | 4 ++ osdopenvg.cc | 15 +++---- osdopenvg.h | 1 - osdvector.cc | 104 +++++++++++++++++++++++++++-------------------- osdvector.h | 44 ++++++++++++-------- region.cc | 18 ++++---- region.h | 2 +- surface.cc | 6 --- surface.h | 1 - surfacevector.cc | 73 ++++++++++++++++----------------- surfacevector.h | 5 +-- tbboxx.cc | 2 +- tvmedia.cc | 45 -------------------- tvmedia.h | 48 ++++++++++++++++++++++ vepg.cc | 13 +++++- 21 files changed, 370 insertions(+), 210 deletions(-) diff --git a/boxstack.cc b/boxstack.cc index cf7890a..b8cfee5 100644 --- a/boxstack.cc +++ b/boxstack.cc @@ -65,7 +65,9 @@ int BoxStack::shutdown() int BoxStack::addVideoDisplay(Boxx* box,VideoDisplay vd) { + boxLock.Lock(); videoStack.push(pair(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 fd697bc..0e2687f 100644 --- a/boxx.cc +++ b/boxx.cc @@ -57,7 +57,7 @@ Boxx::~Boxx() numBoxxes--; Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes); } - +#include 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::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(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 5cf60ef..e6dbce1 100644 --- 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; diff --git a/colour.h b/colour.h index 746b3c1..b99b5eb 100644 --- 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;i0) 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;i0) COMPARE_TEST(grad_pos[i-1]) + } + COMPARE_TEST(ct) + + return false; +} + +#undef COMPARE_TEST + + class SkinFactory { public: static int getNumberofSkins(); diff --git a/demuxerts.cc b/demuxerts.cc index c5e086a..f11ba51 100644 --- a/demuxerts.cc +++ b/demuxerts.cc @@ -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); } } diff --git a/mutex.cc b/mutex.cc index 1ba790a..7b36255 100644 --- a/mutex.cc +++ b/mutex.cc @@ -19,12 +19,18 @@ */ #include "mutex.h" + +#include +#include + 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 21b04b7..bab9f21 100644 --- a/mutex.h +++ b/mutex.h @@ -23,6 +23,7 @@ #ifndef WIN32 #include +#include #else #include #include @@ -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 diff --git a/osdopenvg.cc b/osdopenvg.cc index 45cab21..e59fb79 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -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); -} + diff --git a/osdopenvg.h b/osdopenvg.h index e0a07bd..efcb2ea 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -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); diff --git a/osdvector.cc b/osdvector.cc index aa872fb..a05a709 100644 --- a/osdvector.cc +++ b/osdvector.cc @@ -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::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::iterator curdraw=todraw.begin(); while (curdraw!=todraw.end()) { drawSetTrans(*(*curdraw)); - list::iterator commands=(*(*curdraw)).commands.begin(); - list::iterator end=(*(*curdraw)).commands.end(); + std::vector::iterator commands=(*(*curdraw)).commands.begin(); + std::vector::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& commands) + std::vector& 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::iterator ilitty=commands.begin(); + std::vector::iterator ilitty=commands.begin(); while (ilitty!=commands.end()) { @@ -316,10 +323,10 @@ void OsdVector::removeSurface(const SurfaceVector *surf) } -void OsdVector::dereferenceSVGCommand(list& commands ) +void OsdVector::dereferenceSVGCommand(std::vector& commands ) { - list::iterator sitty = commands.begin(); + std::vector::iterator sitty = commands.begin(); while (sitty != commands.end()) { removeStyleRef((*sitty).getRef()); ImageIndex ii = (*sitty).getImageIndex(); @@ -330,9 +337,9 @@ void OsdVector::dereferenceSVGCommand(list& commands ) } } -void OsdVector::referenceSVGCommand(list& commands ) +void OsdVector::referenceSVGCommand(std::vector& commands ) { - list::iterator sitty=commands.begin(); + std::vector::iterator sitty=commands.begin(); while (sitty!=commands.end()) { incStyleRef((*sitty).getRef()); @@ -475,7 +482,7 @@ void OsdVector::cleanupOrphanedRefs() } - map,unsigned int>::iterator sitty=styles.begin(); + map::iterator sitty=styles.begin(); while (sitty!=styles.end()) { map::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(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*)&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*)&c,c.rgba())]=style_handle; + styles_lastit=styles.insert(std::pair(c,style_handle)).first; } else { - style_handle=styles[pair((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*)&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*)&c,c.rgba()))==styles.end()) - { - surfaces_mutex.Unlock(); - style_handle=createColorRef(c); - surfaces_mutex.Lock(); - styles[pair((Colour*)&c,c.rgba())]=style_handle; - } else { - style_handle=styles[pair((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*)&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; } } diff --git a/osdvector.h b/osdvector.h index 0daae43..fe097e4 100644 --- a/osdvector.h +++ b/osdvector.h @@ -25,6 +25,7 @@ #include "colour.h" #include #include +#include #include #include #include @@ -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 commands; + vector 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& commands); + std::vector& 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,unsigned int> styles; + + + map styles; map styles_ref; + map::iterator styles_lastit; + bool styles_lastit_valid; + map::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& commands ); - void referenceSVGCommand(list& commands ); + void dereferenceSVGCommand(std::vector& commands ); + void referenceSVGCommand(std::vector& commands ); void cleanupOrphanedRefs(); @@ -399,10 +405,12 @@ protected: - list scommands; + std::list scommands; Mutex surfaces_mutex; + float byte_char_width[256]; + void drawSurfaces(); }; diff --git a/region.cc b/region.cc index c46944e..b556277 100644 --- 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); diff --git a/region.h b/region.h index ad23113..2b191b1 100644 --- 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 diff --git a/surface.cc b/surface.cc index 390c237..d28b178 100644 --- a/surface.cc +++ b/surface.cc @@ -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) diff --git a/surface.h b/surface.h index 228cd42..bb3a6f9 100644 --- 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; diff --git a/surfacevector.cc b/surfacevector.cc index af23530..8167128 100644 --- a/surfacevector.cc +++ b/surfacevector.cc @@ -29,12 +29,13 @@ SurfaceVector::SurfaceVector(OsdVector* vosd) { osd=vosd; + commands.reserve(2048); } SurfaceVector::~SurfaceVector() { osd->removeSurface(this); - list::iterator itty=commands.begin(); + vector::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::iterator itty=commands.begin(); + vector::iterator itty=commands.begin(); + vector::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::iterator itty=commands.begin(); + vector::iterator itty=commands.begin(); while (itty!=commands.end()) { if ((*itty).TTTest(ox,oy,x,y) ) { diff --git a/surfacevector.h b/surfacevector.h index fb31b17..71c07bc 100644 --- a/surfacevector.h +++ b/surfacevector.h @@ -24,7 +24,7 @@ #include "surface.h" #include "osdvector.h" -#include +#include 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 commands; + std::vector commands; int swidth, sheight; Mutex command_mutex; OsdVector* osd; diff --git a/tbboxx.cc b/tbboxx.cc index 58ce630..4ecd324 100644 --- 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) diff --git a/tvmedia.cc b/tvmedia.cc index feb2577..fd6968e 100644 --- a/tvmedia.cc +++ b/tvmedia.cc @@ -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 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.containercharSet()!=1) mchar=true; + mbstate_t state; + memset((void*)&state,0,sizeof(state)); + UINT textPos; for (textPos = 0; textPos w) // text will not fit in cell { -- 2.39.2