From ae7fffe6e0e5b8209f2e02aca49531e06bf384f4 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Mon, 11 May 2020 21:41:16 +0100 Subject: [PATCH] Formatting --- osdopenvg.cc | 2588 +++++++++++++++++++++++++--------------------- osdopenvg.h | 106 +- osdvector.cc | 1664 ++++++++++++++++------------- osdvector.h | 524 +++++----- surfacevector.cc | 639 +++++++----- surfacevector.h | 8 +- 6 files changed, 3061 insertions(+), 2468 deletions(-) diff --git a/osdopenvg.cc b/osdopenvg.cc index 51119cf..321c214 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -49,19 +49,19 @@ OsdOpenVG::OsdOpenVG() { vgmutex.lock(); taskmutex.lock(); - lastrendertime=getTimeMS(); - display_height=0; - display_width=0; - mode=0; - aspect_correction=1.; + lastrendertime = getTimeMS(); + display_height = 0; + display_width = 0; + mode = 0; + aspect_correction = 1.; bcm_backres = 0; - freetype_inited=false; - wait_id=1; - const char *fontname="Droid Sans:style=Regular"; - cur_fontname=(char*)malloc(strlen(fontname)+1); - strcpy(cur_fontname,fontname); + freetype_inited = false; + wait_id = 1; + const char* fontname = "Droid Sans:style=Regular"; + cur_fontname = (char*)malloc(strlen(fontname) + 1); + strcpy(cur_fontname, fontname); #define EXTERNALPICTURE(name, fname, fileextension) static_artwork_begin[sa_ ## name]=name ## _data; @@ -80,35 +80,42 @@ OsdOpenVG::~OsdOpenVG() if (initted) { - shutdown(); + shutdown(); } if (cur_fontname) free(cur_fontname); + if (freetype_inited) FT_Done_Face(ft_face); // I think the following is broken as it is, but also possibly it shouldn't be free()ing the memory // pointed at anyway, so it's correctly not working?! - if (!fontnames.size()) { - std::vector::iterator itty=fontnames.begin(); - while (itty!=fontnames.end()) { - free((void*)*itty); + if (!fontnames.size()) + { + std::vector::iterator itty = fontnames.begin(); + + while (itty != fontnames.end()) + { + free((void*)*itty); - itty++; - } + itty++; + } } // end - if (fontnames_keys.size()) { - std::vector::iterator itty=fontnames_keys.begin(); - while (itty!=fontnames_keys.end()) { - free((void*)*itty); - itty++; - } + if (fontnames_keys.size()) + { + std::vector::iterator itty = fontnames_keys.begin(); + + while (itty != fontnames_keys.end()) + { + free((void*)*itty); + itty++; } + } vgmutex.unlock(); taskmutex.unlock(); @@ -119,195 +126,237 @@ OsdOpenVG::~OsdOpenVG() int OsdOpenVG::init() { if (initted) return 0; + reader.init(); - //init broadcom chipset (Move to video?) + //init broadcom chipset (Move to video?) - //First get connection to egl - egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY); + //First get connection to egl + egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + + if (egl_display == EGL_NO_DISPLAY) + { + Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x", eglGetError()); + vgmutex.unlock(); + return 0; + } + + + + if (eglInitialize(egl_display, NULL, NULL) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x", eglGetError()); + vgmutex.unlock(); + return 0; + } + - if (egl_display==EGL_NO_DISPLAY) { - Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x",eglGetError()); - vgmutex.unlock(); - return 0; - } + const char* query_str = eglQueryString(egl_display, EGL_CLIENT_APIS); + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", eglGetError()); + query_str = eglQueryString(egl_display, EGL_EXTENSIONS); - if (eglInitialize(egl_display, NULL, NULL)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x",eglGetError()); - vgmutex.unlock(); - return 0; - } + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", eglGetError()); + if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api failed! %x", eglGetError()); + vgmutex.unlock(); + return 0; + } - const char *query_str=eglQueryString(egl_display,EGL_CLIENT_APIS); - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError()); - query_str=eglQueryString(egl_display,EGL_EXTENSIONS); - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError()); + const EGLint attributs[] = + { + EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, + EGL_CONFORMANT, EGL_OPENVG_BIT, + EGL_NONE + }; // Here, we might have to select the resolution! - if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api failed! %x",eglGetError()); - vgmutex.unlock(); - return 0; - } - const EGLint attributs[]={ - EGL_RED_SIZE,8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, - EGL_CONFORMANT, EGL_OPENVG_BIT, - EGL_NONE - }; // Here, we might have to select the resolution! + EGLint number; + if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %x", eglGetError()); + vgmutex.unlock(); + return 0; + } - EGLint number; - if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %x",eglGetError()); - vgmutex.unlock(); - return 0; - } + egl_context = eglCreateContext(egl_display, egl_ourconfig, NULL, NULL); + if (egl_context == EGL_NO_CONTEXT) + { + Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %x", eglGetError()); + vgmutex.unlock(); + return 0; + } - egl_context=eglCreateContext(egl_display,egl_ourconfig,NULL,NULL); - if (egl_context==EGL_NO_CONTEXT) { - Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %x",eglGetError()); - vgmutex.unlock(); - return 0; - } + // warning broadcom specific, get display size! + display_width = display_height = 0; - // warning broadcom specific, get display size! - display_width=display_height=0; - if (graphics_get_display_size(0, &display_width, &display_height)<0) { - Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) "); - vgmutex.unlock(); - return 0; - } - Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ",display_width, display_height); - VC_RECT_T dst_rect = {0, 0, (int32_t)display_width, (int32_t)display_height}; - VC_RECT_T src_rect={0,0,BACKBUFFER_WIDTH <<16,BACKBUFFER_HEIGHT<<16}; - VC_RECT_T src_rect_bg={0,0,16<<16,16<<16}; -// VC_RECT_T src_rect_im={0,0,16,16}; + if (graphics_get_display_size(0, &display_width, &display_height) < 0) + { + Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) "); + vgmutex.unlock(); + return 0; + } - uint32_t back_image_ptr; - bcm_backres=vc_dispmanx_resource_create(VC_IMAGE_RGBX32,16,16,&back_image_ptr); + Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ", display_width, display_height); + VC_RECT_T dst_rect = {0, 0, (int32_t)display_width, (int32_t)display_height}; + VC_RECT_T src_rect = {0, 0, BACKBUFFER_WIDTH << 16, BACKBUFFER_HEIGHT << 16}; + VC_RECT_T src_rect_bg = {0, 0, 16 << 16, 16 << 16}; + // VC_RECT_T src_rect_im={0,0,16,16}; + uint32_t back_image_ptr; + bcm_backres = vc_dispmanx_resource_create(VC_IMAGE_RGBX32, 16, 16, &back_image_ptr); - updateBackgroundColor(DrawStyle::WALLPAPER); + updateBackgroundColor(DrawStyle::WALLPAPER); - DISPMANX_UPDATE_HANDLE_T bcm_update; - bcm_display=vc_dispmanx_display_open(0); - bcm_update=vc_dispmanx_update_start(0); - bcm_element=vc_dispmanx_element_add(bcm_update,bcm_display, - 2,&dst_rect, 0, - &src_rect,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0); + DISPMANX_UPDATE_HANDLE_T bcm_update; + bcm_display = vc_dispmanx_display_open(0); + bcm_update = vc_dispmanx_update_start(0); + bcm_element = vc_dispmanx_element_add(bcm_update, bcm_display, + 2, &dst_rect, 0, + &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0); - bcm_background=vc_dispmanx_element_add(bcm_update,bcm_display, - 0,&dst_rect,bcm_backres , - &src_rect_bg,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0); - vc_dispmanx_update_submit_sync(bcm_update); + bcm_background = vc_dispmanx_element_add(bcm_update, bcm_display, + 0, &dst_rect, bcm_backres, + &src_rect_bg, DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0); + vc_dispmanx_update_submit_sync(bcm_update); - static EGL_DISPMANX_WINDOW_T nativewindow; - nativewindow.element=bcm_element; - nativewindow.height=BACKBUFFER_HEIGHT; - nativewindow.width=BACKBUFFER_WIDTH; - egl_surface = eglCreateWindowSurface(egl_display,egl_ourconfig, &nativewindow,NULL ); - if (egl_surface==EGL_NO_SURFACE) { - Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!"); - vgmutex.unlock(); - return 0; - } - Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current in1%d",syscall(SYS_gettid)); - if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed"); - vgmutex.unlock(); - return 0; - } - // Test stuff + static EGL_DISPMANX_WINDOW_T nativewindow; + nativewindow.element = bcm_element; + nativewindow.height = BACKBUFFER_HEIGHT; + nativewindow.width = BACKBUFFER_WIDTH; - query_str=(const char*)vgGetString(VG_VERSION) ; - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError()); + egl_surface = eglCreateWindowSurface(egl_display, egl_ourconfig, &nativewindow, NULL ); - query_str=(const char*)vgGetString(VG_VENDOR) ; - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError()); + if (egl_surface == EGL_NO_SURFACE) + { + Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!"); + vgmutex.unlock(); + return 0; + } - query_str=(const char*)vgGetString(VG_RENDERER) ; - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError()); + Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current in1%d", syscall(SYS_gettid)); - query_str=(const char*)vgGetString(VG_EXTENSIONS) ; - if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); - else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError()); + if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed"); + vgmutex.unlock(); + return 0; + } - aspect_correction= ((float)BACKBUFFER_HEIGHT)/576.f/(((float)BACKBUFFER_WIDTH)/720.f); + // Test stuff + + query_str = (const char*)vgGetString(VG_VERSION) ; + + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError()); + + query_str = (const char*)vgGetString(VG_VENDOR) ; + + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError()); + + query_str = (const char*)vgGetString(VG_RENDERER) ; + + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError()); + + query_str = (const char*)vgGetString(VG_EXTENSIONS) ; + + if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError()); + + aspect_correction = ((float)BACKBUFFER_HEIGHT) / 576.f / (((float)BACKBUFFER_WIDTH) / 720.f); initPaths(); - if (!fontnames.size()) { - //inspired by and copied from vdr's code - FcInit(); - FcObjectSet *objset= FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL); - FcPattern * pattern=FcPatternCreate(); - FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); - FcFontSet* fonts = FcFontList(NULL, pattern, objset); - for (int i=0; infont;i++) { - char *s = (char *)FcNameUnparse(fonts->fonts[i]); - - if (s) { - char *c= strchr(s,':'); - if (c) { - char *s2= strchr(c+1,','); - if (s2) *s2=0; - } - char *p=strchr(s,','); - if (p) { - if (!c) *p=0; - else memmove(p,c,strlen(c)+1); - } - char *key=(char*)malloc(strlen(s)+1); - strcpy(key,s); - fontnames_keys.push_back(key); - char *s2=strstr(s,"style="); - if (s2) { - memmove(s2,s2+6,strlen(s2+6)+1); - } - fontnames.push_back(s); - } - } - FcFontSetDestroy(fonts); - FcPatternDestroy(pattern); - FcObjectSetDestroy(objset); + + if (!fontnames.size()) + { + //inspired by and copied from vdr's code + FcInit(); + FcObjectSet* objset = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL); + FcPattern* pattern = FcPatternCreate(); + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcFontSet* fonts = FcFontList(NULL, pattern, objset); + + for (int i = 0; i < fonts->nfont; i++) + { + char* s = (char*)FcNameUnparse(fonts->fonts[i]); + + if (s) + { + char* c = strchr(s, ':'); + + if (c) + { + char* s2 = strchr(c + 1, ','); + + if (s2) *s2 = 0; + } + + char* p = strchr(s, ','); + + if (p) + { + if (!c) *p = 0; + else memmove(p, c, strlen(c) + 1); + } + + char* key = (char*)malloc(strlen(s) + 1); + strcpy(key, s); + fontnames_keys.push_back(key); + char* s2 = strstr(s, "style="); + + if (s2) + { + memmove(s2, s2 + 6, strlen(s2 + 6) + 1); + } + + fontnames.push_back(s); + } + } + + FcFontSetDestroy(fonts); + FcPatternDestroy(pattern); + FcObjectSetDestroy(objset); } - if (!loadFont(false)) { - return 0; + if (!loadFont(false)) + { + return 0; } - vgttfont=vgCreateFont(0); - vgttpaint=vgCreatePaint(); + + vgttfont = vgCreateFont(0); + vgttpaint = vgCreatePaint(); vgSetParameteri( vgttpaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); - vgSetColor(vgttpaint,0xffffffff); + vgSetColor(vgttpaint, 0xffffffff); eglSwapInterval(egl_display, 1 ); - Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out 1%d",syscall(SYS_gettid)); + Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out 1%d", syscall(SYS_gettid)); eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); //Now we will create the Screen initted = true; // must set this here or create surface won't work /*if (((VideoOMX*)Video::getInstance())->initUsingOSDObjects()!=1) { //call Video for init stuff - return 0; + return 0; }*/ @@ -316,8 +365,8 @@ int OsdOpenVG::init() vgmutex.unlock(); #ifdef PICTURE_DECODER_OMX - imageomx=new ImageOMX(&reader); - reader.addDecoder(imageomx); + imageomx = new ImageOMX(&reader); + reader.addDecoder(imageomx); #endif @@ -326,65 +375,77 @@ int OsdOpenVG::init() void OsdOpenVG::updateBackgroundColor(DrawStyle bg) { - unsigned int color[16*16]; - if (!bcm_backres) return; - VC_RECT_T src_rect_im={0,0,16,16}; + unsigned int color[16 * 16]; - if (bg.ft!=DrawStyle::GradientLinear) { - bg.grad_col[0]=bg; - } - //memset(color,0xFF,sizeof(unsigned int)*4*8); - for (int j=0;j<16;j++) { - int helpr=(((15-j)*bg.red)+(j*bg.grad_col[0].red))/15; - int helpb=(((15-j)*bg.blue)+(j*bg.grad_col[0].blue))/15; - int helpg=(((15-j)*bg.green)+(j*bg.grad_col[0].green))/15; - //unsigned int cur_col=help | (help<< 8) | (help<< 16) | (0xFF<< 24); - unsigned int cur_col=helpr | (helpg<< (8)) | (helpb<< (16)) | (0xFF<< (24)); - for (int i=0;i<16;i++) { - color[i+16*j]=cur_col; - } - } - vc_dispmanx_resource_write_data(bcm_backres,VC_IMAGE_RGBX32,16*4,color,&src_rect_im); + if (!bcm_backres) return; + + VC_RECT_T src_rect_im = {0, 0, 16, 16}; + + if (bg.ft != DrawStyle::GradientLinear) + { + bg.grad_col[0] = bg; + } + + //memset(color,0xFF,sizeof(unsigned int)*4*8); + for (int j = 0; j < 16; j++) + { + int helpr = (((15 - j) * bg.red) + (j * bg.grad_col[0].red)) / 15; + int helpb = (((15 - j) * bg.blue) + (j * bg.grad_col[0].blue)) / 15; + int helpg = (((15 - j) * bg.green) + (j * bg.grad_col[0].green)) / 15; + //unsigned int cur_col=help | (help<< 8) | (help<< 16) | (0xFF<< 24); + unsigned int cur_col = helpr | (helpg << (8)) | (helpb << (16)) | (0xFF << (24)); + + for (int i = 0; i < 16; i++) + { + color[i + 16 * j] = cur_col; + } + } + + vc_dispmanx_resource_write_data(bcm_backres, VC_IMAGE_RGBX32, 16 * 4, color, &src_rect_im); } -void OsdOpenVG::getScreenSize(int &width, int &height) +void OsdOpenVG::getScreenSize(int& width, int& height) { - width=BACKBUFFER_WIDTH; - height=BACKBUFFER_HEIGHT; + width = BACKBUFFER_WIDTH; + height = BACKBUFFER_HEIGHT; } -void OsdOpenVG::getRealScreenSize(int &width, int &height) +void OsdOpenVG::getRealScreenSize(int& width, int& height) { - width=display_width; - height=display_height; + width = display_width; + height = display_height; } -bool OsdOpenVG::screenShot(void *buffer, int width, int height, bool osd /*include osd*/) +bool OsdOpenVG::screenShot(void* buffer, int width, int height, bool osd /*include osd*/) { - if (!initted) return false; - if (!buffer) return false; - - DISPMANX_RESOURCE_HANDLE_T res; - DISPMANX_DISPLAY_HANDLE_T display; - - uint32_t image_ptr; - VC_RECT_T rect; - res=vc_dispmanx_resource_create(VC_IMAGE_RGBA32,width,height,&image_ptr); - display=vc_dispmanx_display_open(0); - if (!osd) { - vc_dispmanx_snapshot(display, res, - (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL/*|DISPMANX_SNAPSHOT_PACK*/)); - } - else - { - vc_dispmanx_snapshot(display, res, - (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_FILL)); - } - vc_dispmanx_rect_set(&rect,0,0,width,height); - vc_dispmanx_resource_read_data(res, &rect, buffer, width*4); - vc_dispmanx_resource_delete(res); - vc_dispmanx_display_close(display); - return true; + if (!initted) return false; + + if (!buffer) return false; + + DISPMANX_RESOURCE_HANDLE_T res; + DISPMANX_DISPLAY_HANDLE_T display; + + uint32_t image_ptr; + VC_RECT_T rect; + res = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, width, height, &image_ptr); + display = vc_dispmanx_display_open(0); + + if (!osd) + { + vc_dispmanx_snapshot(display, res, + (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_NO_RGB | DISPMANX_SNAPSHOT_FILL/*|DISPMANX_SNAPSHOT_PACK*/)); + } + else + { + vc_dispmanx_snapshot(display, res, + (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_FILL)); + } + + vc_dispmanx_rect_set(&rect, 0, 0, width, height); + vc_dispmanx_resource_read_data(res, &rect, buffer, width * 4); + vc_dispmanx_resource_delete(res); + vc_dispmanx_display_close(display); + return true; } @@ -393,53 +454,53 @@ void OsdOpenVG::initPaths() { - VGPath current; - current=vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F,1.f,0.f, - 0,0,VG_PATH_CAPABILITY_ALL); - - vguLine(current,0.f,0.f,1.f,0.f); - // HorzLine - std_paths[PIHorzLine]=current; - - current=vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F,1.f,0.f, - 0,0,VG_PATH_CAPABILITY_ALL); - vguLine(current,0.f,0.f,0.f,1.f); - // VertLine - std_paths[PIVertLine]=current; - - current=vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F,1.f,0.f, - 0,0,VG_PATH_CAPABILITY_ALL); - //vguRect(current,0.f,0.f,1.f,1.f); - vguRect(current,0.f,0.f,1.f,1.f); - // Rectabgle - std_paths[PIRectangle]=current; - - current=vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F,1.f,0.f, - 0,0,0); - vguEllipse(current,0.f,0.f,1.f,1.f); - // Point - std_paths[PIPoint]=current; + VGPath current; + current = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1.f, 0.f, + 0, 0, VG_PATH_CAPABILITY_ALL); + + vguLine(current, 0.f, 0.f, 1.f, 0.f); + // HorzLine + std_paths[PIHorzLine] = current; + + current = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1.f, 0.f, + 0, 0, VG_PATH_CAPABILITY_ALL); + vguLine(current, 0.f, 0.f, 0.f, 1.f); + // VertLine + std_paths[PIVertLine] = current; + + current = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1.f, 0.f, + 0, 0, VG_PATH_CAPABILITY_ALL); + //vguRect(current,0.f,0.f,1.f,1.f); + vguRect(current, 0.f, 0.f, 1.f, 1.f); + // Rectabgle + std_paths[PIRectangle] = current; + + current = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1.f, 0.f, + 0, 0, 0); + vguEllipse(current, 0.f, 0.f, 1.f, 1.f); + // Point + std_paths[PIPoint] = current; } void OsdOpenVG::destroyPaths() { - vgDestroyPath(std_paths[PIHorzLine]); - vgDestroyPath(std_paths[PIVertLine]); - vgDestroyPath(std_paths[PIRectangle]); - vgDestroyPath(std_paths[PIPoint]); + vgDestroyPath(std_paths[PIHorzLine]); + vgDestroyPath(std_paths[PIVertLine]); + vgDestroyPath(std_paths[PIRectangle]); + vgDestroyPath(std_paths[PIPoint]); } int OsdOpenVG::stopUpdate() { - threadStop(); - processTasks(); - return 1; + threadStop(); + processTasks(); + return 1; } /* void OsdOpenVG::purgeAllReferences() @@ -482,8 +543,10 @@ int OsdOpenVG::shutdown() { reader.shutdown(); #ifdef PICTURE_DECODER_OMX - if (imageomx) reader.removeDecoder(imageomx); - imageomx=NULL; + + if (imageomx) reader.removeDecoder(imageomx); + + imageomx = NULL; #endif if (!initted) return 0; @@ -492,12 +555,16 @@ int OsdOpenVG::shutdown() Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1"); threadStop(); Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1a"); + //(((VideoOMX*)Video::getInstance())->shutdownUsingOSDObjects()); - if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in shutdown %x",eglGetError()); + if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in shutdown %x", eglGetError()); } - if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x",eglGetError()); + + if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x", eglGetError()); } Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark2"); @@ -515,27 +582,33 @@ int OsdOpenVG::shutdown() vgDestroyFont(vgttfont); vgDestroyPaint(vgttpaint); destroyPaths(); - float colclear[]={0.8f,0.8f,0.8f,1.f}; - vgSetfv(VG_CLEAR_COLOR,4,colclear); - vgClear(0,0,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT); + float colclear[] = {0.8f, 0.8f, 0.8f, 1.f}; + vgSetfv(VG_CLEAR_COLOR, 4, colclear); + vgClear(0, 0, BACKBUFFER_WIDTH, BACKBUFFER_HEIGHT); eglSwapBuffers(egl_display, egl_surface); Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out final"); eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); - if (eglDestroySurface(egl_display,egl_surface)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::ERR, "eglDestroySurface failed %x",eglGetError()); + + if (eglDestroySurface(egl_display, egl_surface) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::ERR, "eglDestroySurface failed %x", eglGetError()); } - if (eglDestroyContext(egl_display,egl_context)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::ERR, "eglDestroyContext failed %x",eglGetError()); + + if (eglDestroyContext(egl_display, egl_context) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::ERR, "eglDestroyContext failed %x", eglGetError()); } - if (eglTerminate(egl_display )==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::ERR, "eglTerminate failed %x",eglGetError()); + + if (eglTerminate(egl_display ) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::ERR, "eglTerminate failed %x", eglGetError()); } DISPMANX_UPDATE_HANDLE_T bcm_update; - bcm_update=vc_dispmanx_update_start(0); + bcm_update = vc_dispmanx_update_start(0); - vc_dispmanx_element_remove(bcm_update,bcm_element); - vc_dispmanx_element_remove(bcm_update,bcm_background); + vc_dispmanx_element_remove(bcm_update, bcm_element); + vc_dispmanx_element_remove(bcm_update, bcm_background); vc_dispmanx_update_submit_sync(bcm_update); vc_dispmanx_resource_delete(bcm_backres); bcm_backres = 0; @@ -551,75 +624,100 @@ int OsdOpenVG::shutdown() void OsdOpenVG::threadMethod() { - // We have to claim the egl context for this thread - Log::getInstance()->log("OSD", Log::NOTICE, "Entering drawing thread"); - if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %x",eglGetError()); - return; - } - if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x",eglGetError()); - return; - } - int ts=0; - while (true) - { - ts=1; - //unsigned int waittime=1; - - if (initted) { - - long long time1 = getTimeMS(); - if ((time1 - lastrendertime) > 200) {//5 fps for OSD updates are enough, avoids tearing - InternalRendering(); - lastrendertime = getTimeMS(); - - ts = 10; - } - else { - ts = time1 - lastrendertime; - - } - if (processTasks()) ts=0; - } - if (!threadIsActive()) { - 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(); - } - if (ts!=0) { - struct timespec target_time; - clock_gettime(CLOCK_REALTIME,&target_time); - target_time.tv_nsec+=1000000LL*ts; - if (target_time.tv_nsec>999999999) { - target_time.tv_nsec-=1000000000L; - target_time.tv_sec+=1; - } - threadLock(); - threadWaitForSignalTimed(&target_time); - threadUnlock(); - } - //Sleep(1); - } - eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); + // We have to claim the egl context for this thread + Log::getInstance()->log("OSD", Log::NOTICE, "Entering drawing thread"); + + if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %x", eglGetError()); + return; + } + + if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE) + { + Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x", eglGetError()); + return; + } + + int ts = 0; + + while (true) + { + ts = 1; + //unsigned int waittime=1; + + if (initted) + { + + long long time1 = getTimeMS(); + + if ((time1 - lastrendertime) > 200) //5 fps for OSD updates are enough, avoids tearing + { + InternalRendering(); + lastrendertime = getTimeMS(); + + ts = 10; + } + else + { + ts = time1 - lastrendertime; + + } + + if (processTasks()) ts = 0; + } + + if (!threadIsActive()) + { + 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(); + } + + if (ts != 0) + { + struct timespec target_time; + clock_gettime(CLOCK_REALTIME, &target_time); + target_time.tv_nsec += 1000000LL * ts; + + if (target_time.tv_nsec > 999999999) + { + target_time.tv_nsec -= 1000000000L; + target_time.tv_sec += 1; + } + + threadLock(); + threadWaitForSignalTimed(&target_time); + threadUnlock(); + } + + //Sleep(1); + } + + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); } -void OsdOpenVG::InternalRendering(){ - vgmutex.lock(); - Colour bg=DrawStyle::WALLPAPER; - float colclear[]={1.f,1.0f,1.f,1.f}; - if (bg.alpha==0) colclear[3]=0.f; - vgSetfv(VG_CLEAR_COLOR,4,colclear); - vgClear(0,0,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT); - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); +void OsdOpenVG::InternalRendering() +{ + vgmutex.lock(); + Colour bg = DrawStyle::WALLPAPER; + float colclear[] = {1.f, 1.0f, 1.f, 1.f}; + + if (bg.alpha == 0) colclear[3] = 0.f; + vgSetfv(VG_CLEAR_COLOR, 4, colclear); + vgClear(0, 0, BACKBUFFER_WIDTH, BACKBUFFER_HEIGHT); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); - drawSurfaces(); //iterate through and draws all commands - //Show it to the user! - eglSwapBuffers(egl_display, egl_surface); - vgmutex.unlock(); + drawSurfaces(); //iterate through and draws all commands + + //Show it to the user! + eglSwapBuffers(egl_display, egl_surface); + vgmutex.unlock(); } @@ -627,920 +725,1102 @@ void OsdOpenVG::InternalRendering(){ float OsdOpenVG::getFontHeight() { - return font_height; //dummy + return font_height; //dummy } 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]; + 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]; } unsigned int OsdOpenVG::loadTTchar(cTeletextChar c) { - unsigned int glyph_index=c.getGlyphIndex(); - if (tt_font_chars.find(glyph_index)!=tt_font_chars.end()) - { - return glyph_index; - } + unsigned int glyph_index = c.getGlyphIndex(); - unsigned int buffer[10]; - const VGfloat glyphOrigin[] = { 0.f, 0.f }; - const VGfloat escapement[] = { 12.f, 0.f }; - unsigned int * charmap = GetFontChar(c, buffer); - if (!charmap) { //invalid char - return 0; - } - for (int i=0;i<10;i++) { - buffer[i]=charmap[i]>>4; - } + if (tt_font_chars.find(glyph_index) != tt_font_chars.end()) + { + return glyph_index; + } + + unsigned int buffer[10]; + const VGfloat glyphOrigin[] = { 0.f, 0.f }; + const VGfloat escapement[] = { 12.f, 0.f }; + unsigned int* charmap = GetFontChar(c, buffer); - VGImage handle = vgCreateImage( - VG_A_8, - 12, - 10, - VG_IMAGE_QUALITY_NONANTIALIASED | VG_IMAGE_QUALITY_FASTER - | VG_IMAGE_QUALITY_BETTER); - vgImageSubData(handle, buffer, 4, VG_A_1, 0, 0, 12, 10); - vgSetGlyphToImage( - vgttfont, - glyph_index, - handle, (VGfloat*)glyphOrigin, (VGfloat*)escapement); - vgDestroyImage(handle); - tt_font_chars[glyph_index]=1; - - return glyph_index; + if (!charmap) //invalid char + { + return 0; + } + + for (int i = 0; i < 10; i++) + { + buffer[i] = charmap[i] >> 4; + } + + VGImage handle = vgCreateImage( + VG_A_8, + 12, + 10, + VG_IMAGE_QUALITY_NONANTIALIASED | VG_IMAGE_QUALITY_FASTER + | VG_IMAGE_QUALITY_BETTER); + vgImageSubData(handle, buffer, 4, VG_A_1, 0, 0, 12, 10); + vgSetGlyphToImage( + vgttfont, + glyph_index, + handle, (VGfloat*)glyphOrigin, (VGfloat*)escapement); + vgDestroyImage(handle); + tt_font_chars[glyph_index] = 1; + + return glyph_index; } -int OsdOpenVG::getFontNames(const char *** names,const char *** names_keys) +int OsdOpenVG::getFontNames(const char*** names, const char*** names_keys) { - *names=(const char**)&(fontnames[0]); - *names_keys=(const char**)&(fontnames_keys[0]); - return fontnames.size(); + *names = (const char**) & (fontnames[0]); + *names_keys = (const char**) & (fontnames_keys[0]); + return fontnames.size(); } -void OsdOpenVG::setFont(const char * fontname) { +void OsdOpenVG::setFont(const char* fontname) +{ + + if (strcmp(fontname, cur_fontname)) + { + // new font! + if (cur_fontname) free(cur_fontname); - if (strcmp(fontname,cur_fontname)) { - // new font! - if (cur_fontname) free(cur_fontname); - cur_fontname = static_cast(malloc(strlen(fontname)+1)); - strcpy(cur_fontname,fontname); + cur_fontname = static_cast(malloc(strlen(fontname) + 1)); + strcpy(cur_fontname, fontname); - struct OpenVGCommand comm; - comm.task=OVGreplacefont; - putOpenVGCommand(comm,false); + struct OpenVGCommand comm; + comm.task = OVGreplacefont; + putOpenVGCommand(comm, false); - } + } } int OsdOpenVG::loadFont(bool newfont) { - int error; - float font_size=16.f; - if (!freetype_inited) { - error=FT_Init_FreeType(&ft_library); - if (error) - { - Log::getInstance()->log("OSD", Log::WARN, "Could not load freetype %x",error); - return 0; - } - } + int error; + float font_size = 16.f; - if (!freetype_inited || newfont) { - //first get the filename algorith extracted from vdr by Klaus Schmidinger - FcInit(); - FcPattern *pattern=FcNameParse((FcChar8*)cur_fontname); - FcPatternAddBool(pattern,FC_SCALABLE,FcTrue); - FcConfigSubstitute(NULL,pattern,FcMatchPattern); - FcDefaultSubstitute(pattern); - FcResult fres; - FcFontSet *fonts=FcFontSort(NULL,pattern,FcFalse,NULL,&fres); - FcChar8 *filename=NULL; - if (fonts) { - for (int i=0;infont;i++) { - FcBool canscale; - FcPatternGetBool(fonts->fonts[i],FC_SCALABLE,0,&canscale); - if (canscale){ - FcPatternGetString(fonts->fonts[i],FC_FILE,0,&filename); - break; - } - } - FcFontSetDestroy(fonts); - } else { - Log::getInstance()->log("OSD", Log::CRIT, "Could not locate a font! Abort!"); - return 0; - } - FcPatternDestroy(pattern); - - Log::getInstance()->log("OSD", Log::NOTICE, "Load Font %s: %s", cur_fontname,filename); - // second load the font - FT_Face new_ft_face; - error=FT_New_Face(ft_library,(const char*)filename,0,&new_ft_face ); - if (error) { - Log::getInstance()->log("OSD", Log::WARN, "Could not load font face %x %s",error,filename); - return 0; - } - error=FT_Set_Char_Size(new_ft_face,0,font_size*256,0,0 /*dpi*/); - if (error) { - FT_Done_Face(new_ft_face); - Log::getInstance()->log("OSD", Log::WARN, "Could not set face size %x",error); - return 0; - } - FT_Face old_ft_face=ft_face; // do it thread safe - ft_face=new_ft_face; - if (freetype_inited) FT_Done_Face(old_ft_face);// - freetype_inited=true; - } - vgfont=vgCreateFont(0); - FT_ULong cur_char; - FT_UInt glyph; - font_height=ft_face->size->metrics.height/256.f; - cur_char = FT_Get_First_Char(ft_face,&glyph); - std::vector segments; - std::vector coord; - segments.reserve(256); - coord.reserve(1024); - //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph test %d %x %x %d",cur_char,font_data_end,font_data,glyph); - while (glyph !=0) - { - error=FT_Load_Glyph(ft_face,glyph,FT_LOAD_DEFAULT); - if (error){ - cur_char = FT_Get_Next_Char(ft_face,cur_char,&glyph); - Log::getInstance()->log("OSD", Log::WARN, "Could not load glyph %x %c",error); - continue; - } - VGPath path; - FT_Outline ot=ft_face->glyph->outline; - segments.clear(); - coord.clear(); - - if (ot.n_contours ==0) { - path=VG_INVALID_HANDLE; - } else { - path=vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, - 1.0f,0.f,0,0,VG_PATH_CAPABILITY_ALL); - - /* convert glyph */ - FT_Vector *pt=ot.points; - const char *tags=ot.tags; - const short* cont=ot.contours; - short n_cont=ot.n_contours; - //short n_point=ot.n_points; - //short last_cont=0; - for (short point=0;n_cont!=0;cont++,n_cont--) { - short next_cont=*cont+1; - bool first=true; - char last_tag=0; - short first_point=point; - //Log::getInstance()->log("OSD", Log::DEBUG, "runs %d",*cont); - for (;pointlog("OSD", Log::DEBUG, "tag %d point %d %d: %d %d",tag,fpoint.x,fpoint.y,point,n_point); - if (first) { - segments.push_back(VG_MOVE_TO); - first=false; - } else if (tag &0x1) { //on curve - if (last_tag &0x1) { - segments.push_back(VG_LINE_TO); - } else if (last_tag &0x2){ - segments.push_back(VG_CUBIC_TO); - } else { - segments.push_back(VG_QUAD_TO); - } - - } else { - if (!(tag &0x2)){ - if (!(last_tag &0x1)) { - segments.push_back(VG_QUAD_TO); - int coord_size=coord.size(); - VGfloat x=(coord[coord_size-2]+ ((float)fpoint.x)/256.f)*0.5f*aspect_correction; - VGfloat y=(coord[coord_size-1]+(font_size- ((float)fpoint.y)/256.f))*0.5f; - coord.push_back(x); - coord.push_back(y); - } - } - - - } - last_tag=tag; - coord.push_back(((float)fpoint.x)*aspect_correction/256.); - coord.push_back(font_size-((float)fpoint.y)/256.); - //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph coord %d %d %g %g",fpoint.x,fpoint.y,coord[coord.size()-2],coord[coord.size()-1]); - } - if (!(last_tag &0x1)) { - if (last_tag &0x2) { - segments.push_back(VG_CUBIC_TO); - } else { - segments.push_back(VG_QUAD_TO); - } - coord.push_back(((float)pt[first_point].x)*aspect_correction/256.); - coord.push_back(font_size-((float)pt[first_point].y)/256.); - } - //segments.push_back(VG_CLOSE_PATH); - - - } - vgAppendPathData(path,segments.size(),&segments[0],&coord[0]); - /* for (int m=0;mlog("OSD", Log::DEBUG, "Move To %g %g",coord[n],coord[n+1]);n+=2; break; - case VG_LINE_TO: - Log::getInstance()->log("OSD", Log::DEBUG, "Line To %g %g",coord[n],coord[n+1]);n+=2; break; - case VG_CUBIC_TO: - Log::getInstance()->log("OSD", Log::DEBUG, "Cubic To %g %g %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3],coord[n+4],coord[n+5]);n+=6; break; - case VG_QUAD_TO: - Log::getInstance()->log("OSD", Log::DEBUG, "Quad To %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3]);n+=4; break; - case VG_CLOSE_PATH: - Log::getInstance()->log("OSD", Log::DEBUG, "Close Path"); break; - } - - }*/ - //vguRect(path,0.f,0.f,1.f,1.f); - //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph %d %x",segments.size(),vgGetError()); - } - VGfloat ori[]={0.f,0.f}; - VGfloat esp[]={ft_face->glyph->advance.x/256.f*aspect_correction,ft_face->glyph->advance.y/256.f}; - font_exp_x[glyph]=ft_face->glyph->advance.x/256.f*aspect_correction; //recalculate - - vgSetGlyphToPath(vgfont,glyph,path,VG_FALSE,ori,esp); - //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph %d %d %x",path,glyph,vgGetError()); - if (path!=VG_INVALID_HANDLE) { - vgDestroyPath(path); - } - 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; + if (!freetype_inited) + { + error = FT_Init_FreeType(&ft_library); + + if (error) + { + Log::getInstance()->log("OSD", Log::WARN, "Could not load freetype %x", error); + return 0; + } + } + + if (!freetype_inited || newfont) + { + //first get the filename algorith extracted from vdr by Klaus Schmidinger + FcInit(); + FcPattern* pattern = FcNameParse((FcChar8*)cur_fontname); + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcConfigSubstitute(NULL, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + FcResult fres; + FcFontSet* fonts = FcFontSort(NULL, pattern, FcFalse, NULL, &fres); + FcChar8* filename = NULL; + + if (fonts) + { + for (int i = 0; i < fonts->nfont; i++) + { + FcBool canscale; + FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &canscale); + + if (canscale) + { + FcPatternGetString(fonts->fonts[i], FC_FILE, 0, &filename); + break; + } + } + + FcFontSetDestroy(fonts); + } + else + { + Log::getInstance()->log("OSD", Log::CRIT, "Could not locate a font! Abort!"); + return 0; + } + + FcPatternDestroy(pattern); + + Log::getInstance()->log("OSD", Log::NOTICE, "Load Font %s: %s", cur_fontname, filename); + // second load the font + FT_Face new_ft_face; + error = FT_New_Face(ft_library, (const char*)filename, 0, &new_ft_face ); + + if (error) + { + Log::getInstance()->log("OSD", Log::WARN, "Could not load font face %x %s", error, filename); + return 0; + } + + error = FT_Set_Char_Size(new_ft_face, 0, font_size * 256, 0, 0 /*dpi*/); + + if (error) + { + FT_Done_Face(new_ft_face); + Log::getInstance()->log("OSD", Log::WARN, "Could not set face size %x", error); + return 0; + } + + FT_Face old_ft_face = ft_face; // do it thread safe + ft_face = new_ft_face; + + if (freetype_inited) FT_Done_Face(old_ft_face);// + + freetype_inited = true; + } + + vgfont = vgCreateFont(0); + FT_ULong cur_char; + FT_UInt glyph; + font_height = ft_face->size->metrics.height / 256.f; + cur_char = FT_Get_First_Char(ft_face, &glyph); + std::vector segments; + std::vector coord; + segments.reserve(256); + coord.reserve(1024); + + //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph test %d %x %x %d",cur_char,font_data_end,font_data,glyph); + while (glyph != 0) + { + error = FT_Load_Glyph(ft_face, glyph, FT_LOAD_DEFAULT); + + if (error) + { + cur_char = FT_Get_Next_Char(ft_face, cur_char, &glyph); + Log::getInstance()->log("OSD", Log::WARN, "Could not load glyph %x %c", error); + continue; + } + + VGPath path; + FT_Outline ot = ft_face->glyph->outline; + segments.clear(); + coord.clear(); + + if (ot.n_contours == 0) + { + path = VG_INVALID_HANDLE; + } + else + { + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.f, 0, 0, VG_PATH_CAPABILITY_ALL); + + /* convert glyph */ + FT_Vector* pt = ot.points; + const char* tags = ot.tags; + const short* cont = ot.contours; + short n_cont = ot.n_contours; + + //short n_point=ot.n_points; + //short last_cont=0; + for (short point = 0; n_cont != 0; cont++, n_cont--) + { + short next_cont = *cont + 1; + bool first = true; + char last_tag = 0; + short first_point = point; + + //Log::getInstance()->log("OSD", Log::DEBUG, "runs %d",*cont); + for (; point < next_cont; point++) + { + char tag = tags[point]; + FT_Vector fpoint = pt[point]; + + // Log::getInstance()->log("OSD", Log::DEBUG, "tag %d point %d %d: %d %d",tag,fpoint.x,fpoint.y,point,n_point); + if (first) + { + segments.push_back(VG_MOVE_TO); + first = false; + } + else if (tag & 0x1) //on curve + { + if (last_tag & 0x1) + { + segments.push_back(VG_LINE_TO); + } + else if (last_tag & 0x2) + { + segments.push_back(VG_CUBIC_TO); + } + else + { + segments.push_back(VG_QUAD_TO); + } + + } + else + { + if (!(tag & 0x2)) + { + if (!(last_tag & 0x1)) + { + segments.push_back(VG_QUAD_TO); + int coord_size = coord.size(); + VGfloat x = (coord[coord_size - 2] + ((float)fpoint.x) / 256.f) * 0.5f * aspect_correction; + VGfloat y = (coord[coord_size - 1] + (font_size - ((float)fpoint.y) / 256.f)) * 0.5f; + coord.push_back(x); + coord.push_back(y); + } + } + + + } + + last_tag = tag; + coord.push_back(((float)fpoint.x)*aspect_correction / 256.); + coord.push_back(font_size - ((float)fpoint.y) / 256.); + //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph coord %d %d %g %g",fpoint.x,fpoint.y,coord[coord.size()-2],coord[coord.size()-1]); + } + + if (!(last_tag & 0x1)) + { + if (last_tag & 0x2) + { + segments.push_back(VG_CUBIC_TO); + } + else + { + segments.push_back(VG_QUAD_TO); + } + + coord.push_back(((float)pt[first_point].x)*aspect_correction / 256.); + coord.push_back(font_size - ((float)pt[first_point].y) / 256.); + } + + //segments.push_back(VG_CLOSE_PATH); + + + } + + vgAppendPathData(path, segments.size(), &segments[0], &coord[0]); + /* for (int m=0;mlog("OSD", Log::DEBUG, "Move To %g %g",coord[n],coord[n+1]);n+=2; break; + case VG_LINE_TO: + Log::getInstance()->log("OSD", Log::DEBUG, "Line To %g %g",coord[n],coord[n+1]);n+=2; break; + case VG_CUBIC_TO: + Log::getInstance()->log("OSD", Log::DEBUG, "Cubic To %g %g %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3],coord[n+4],coord[n+5]);n+=6; break; + case VG_QUAD_TO: + Log::getInstance()->log("OSD", Log::DEBUG, "Quad To %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3]);n+=4; break; + case VG_CLOSE_PATH: + Log::getInstance()->log("OSD", Log::DEBUG, "Close Path"); break; + } + + }*/ + //vguRect(path,0.f,0.f,1.f,1.f); + //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph %d %x",segments.size(),vgGetError()); + } + + VGfloat ori[] = {0.f, 0.f}; + VGfloat esp[] = {ft_face->glyph->advance.x / 256.f * aspect_correction, ft_face->glyph->advance.y / 256.f}; + font_exp_x[glyph] = ft_face->glyph->advance.x / 256.f * aspect_correction; //recalculate + + vgSetGlyphToPath(vgfont, glyph, path, VG_FALSE, ori, esp); + + //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph %d %d %x",path,glyph,vgGetError()); + if (path != VG_INVALID_HANDLE) + { + vgDestroyPath(path); + } + + 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; } -void OsdOpenVG::drawSetTrans(SurfaceCommands & sc) +void OsdOpenVG::drawSetTrans(SurfaceCommands& sc) { - vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); - vgLoadIdentity(); - vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f); - vgTranslate(0.f+sc.x,-576.f+sc.y); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f); + vgTranslate(0.f + sc.x, -576.f + sc.y); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); - vgLoadIdentity(); - vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f); - vgTranslate(0.f+sc.x,-576.f+sc.y); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); + vgLoadIdentity(); + vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f); + vgTranslate(0.f + sc.x, -576.f + sc.y); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); - vgLoadIdentity(); - vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f); - vgTranslate(0.f+sc.x,-576.f+sc.y); - clip_shift_x=sc.x; - clip_shift_y=sc.y; + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgLoadIdentity(); + vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f); + vgTranslate(0.f + sc.x, -576.f + sc.y); + clip_shift_x = sc.x; + clip_shift_y = sc.y; - //vgTranslate(0.f+sc.x,576.f-sc.y); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Translate %g %g",sc.x,sc.y); + //vgTranslate(0.f+sc.x,576.f-sc.y); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Translate %g %g",sc.x,sc.y); } -void OsdOpenVG::executeDrawCommand(SVGCommand & command) +void OsdOpenVG::executeDrawCommand(SVGCommand& command) { - VGfloat save_matrix[9]; - VGfloat save_matrix2[9]; - switch (command.instr) { - case DrawPath: { - vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); - // VGuint rgba; - // rgba = vgGetColor((VGPaint) command.reference); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Path %d %x %g %g %g %g",command.reference,command.target.path_index,command.x,command.y,command.w,command.h); - //vgSeti(VG_FILL_RULE,); - - vgGetMatrix(save_matrix); - vgSetPaint((VGPaint) command.reference,VG_FILL_PATH); - vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH); - vgTranslate(command.x,command.y); - vgScale(command.w,command.h); - vgDrawPath(std_paths[command.target.path_index],VG_FILL_PATH); - vgLoadMatrix(save_matrix); - } break; - case DrawImage: { - vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); - vgGetMatrix(save_matrix); - VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH); - VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT); - - - //vgScale(command.w,command.h); - - if (command.reference) { //special behaviout for bw images they act as a mask on the current paint - vgTranslate(command.x,command.y); - vgSetPaint((VGPaint) command.reference,VG_FILL_PATH); - vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH); - vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL); - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); - vgScale(aspect_correction,1.f); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); - vgGetMatrix(save_matrix2); - vgScale(imagewidth,imageheight); - } else { - - //vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT)); - float scalex=command.w/imagewidth; - float scaley=command.h/imageheight; - float tx=command.x; - float ty=command.y; - if (command.corner == TopLeftLimited) { - if (scalex !=0.f && scaley !=0.f) { - float imageaspect=imagewidth/imageheight; - float boxaspect=command.w/command.h/aspect_correction; - if (imageaspect > boxaspect) { - scaley=0.f; - ty+=(command.h-imageheight * scalex/aspect_correction)*0.5f; - } else { - scalex=0.f; - tx+=(command.w-imagewidth * scaley*aspect_correction)*0.5f; - } - - } - - } - if (scalex==0.f && scaley==0.f) { - scalex=aspect_correction; - scaley=1.f; - } else if (scalex==0.f) { - scalex=scaley*aspect_correction; - } else if (scaley==0.f) { - scaley=scalex/aspect_correction; - } - - - if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle) - { - ty-=imageheight * scaley; - } - - if (command.corner == BottomRight || command.corner == TopRight) - { - tx-=imagewidth * scalex; - } - - if (command.corner == BottomMiddle || command.corner == TopMiddle) - { - tx-=imagewidth * scalex *0.5f; - } - - vgTranslate(tx,ty); - //vgScale(command.w/imagewidth,command.h/imageheight); - vgScale(scalex,scaley); - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); - vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL); - //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Scale %g %g %g %g %g %g",command.w,imagewidth,command.h,imageheight,scalex,scaley); - } - - - //vgLoadIdentity(); - //vgTranslate(200.f,500.f); - //vgScale(100.f,100.f); - - vgDrawImage((VGImage) command.target.image); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Image %d %x %g %g %g %g %x",command.reference,command.target.image,command.x,command.y,command.w,command.h, - // vgGetError()); - if (command.reference) { - vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); - vgLoadMatrix(save_matrix2); - } - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); - - vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); - vgLoadMatrix(save_matrix); - } break; - case DrawGlyph: { - vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); - vgGetMatrix(save_matrix); - vgSetPaint((VGPaint) command.reference,VG_FILL_PATH); - vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH); - vgTranslate(command.x,command.y); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); - vgGetMatrix(save_matrix2); - unsigned int glyph_index=FT_Get_Char_Index(ft_face,command.target.textchar); - vgScale(font_exp_x[glyph_index],font_height); - - - VGfloat gori[]={0.,0.}; - vgSetfv(VG_GLYPH_ORIGIN,2,gori); - - - vgDrawGlyph(vgfont,glyph_index,VG_FILL_PATH,VG_FALSE); - //vgDrawPath(std_paths[Rectangle],VG_FILL_PATH); - /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw Glyph %d %c %d %g %g %x",command.reference,command.target.textchar,glyph_index,command.x,command.y, - vgGetError());*/ - vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); - vgLoadMatrix(save_matrix); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); - vgLoadMatrix(save_matrix2); - - vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); - } break; - case DrawTTchar:{ - cTeletextChar tchar; - tchar.setInternal(command.target.ttchar); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); - vgGetMatrix(save_matrix); - enumTeletextColor ttforegcolour=tchar.GetFGColor(); - enumTeletextColor ttbackgcolour=tchar.GetBGColor(); - if (tchar.GetBoxedOut()) { - ttforegcolour=ttcTransparent; - ttbackgcolour=ttcTransparent; - } - vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL); - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); - - - vgTranslate(command.x+command.w*11.85f*1.4f,command.y+command.h*19.75f); - VGfloat gori[]={0.,0.}; - vgSetfv(VG_GLYPH_ORIGIN,2,gori); - - vgScale(-1.4f,2.f); - unsigned int color=Surface::enumTeletextColorToCoulour(ttbackgcolour).rgba(); - color=color<<8 | (color &0xff000000)>>24; - vgSetColor(vgttpaint,color); - vgSetPaint((VGPaint) vgttpaint,VG_FILL_PATH); - vgSetPaint((VGPaint) vgttpaint,VG_STROKE_PATH); - cTeletextChar filled; - filled.setInternal(0x187f); - unsigned int glyph_index=loadTTchar(filled); - vgDrawGlyph(vgttfont,glyph_index,VG_FILL_PATH,VG_FALSE); - - color=Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(); - color=color<<8 | (color &0xff000000)>>24; - vgSetColor(vgttpaint,color); - vgSetPaint((VGPaint) vgttpaint,VG_FILL_PATH); - vgSetPaint((VGPaint) vgttpaint,VG_STROKE_PATH); - glyph_index=loadTTchar(tchar); - vgDrawGlyph(vgttfont,glyph_index,VG_FILL_PATH,VG_FALSE); - - /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw TTchar %x %x %x %x",glyph_index,ttforegcolour,Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(), - vgGetColor(vgttpaint));*/ - - - vgLoadMatrix(save_matrix); - vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); - vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL); - vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); - - }break; - case DrawClipping: { - VGint coords[4]={0,0,0,0}; - coords[0]= ((command.x+clip_shift_x)*((float)BACKBUFFER_WIDTH)/720.f); - coords[1]= ((576.f-command.y-clip_shift_y-command.h)*((float)BACKBUFFER_HEIGHT)/576.f); - coords[2]= ((command.w-1.f)*((float)BACKBUFFER_WIDTH)/720.f); - coords[3]= ((command.h-1.f)*((float)BACKBUFFER_HEIGHT)/576.f); - vgSetiv(VG_SCISSOR_RECTS, 4,coords); - if (command.w==0.f && command.h==0.f) - vgSeti(VG_SCISSORING,VG_FALSE); - else vgSeti(VG_SCISSORING,VG_TRUE); - } break; - - case DrawImageLoading: - case DrawNoop: - {} - } + VGfloat save_matrix[9]; + VGfloat save_matrix2[9]; + + switch (command.instr) + { + case DrawPath: + { + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + // VGuint rgba; + // rgba = vgGetColor((VGPaint) command.reference); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Path %d %x %g %g %g %g",command.reference,command.target.path_index,command.x,command.y,command.w,command.h); + //vgSeti(VG_FILL_RULE,); + + vgGetMatrix(save_matrix); + vgSetPaint((VGPaint) command.reference, VG_FILL_PATH); + vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH); + vgTranslate(command.x, command.y); + vgScale(command.w, command.h); + vgDrawPath(std_paths[command.target.path_index], VG_FILL_PATH); + vgLoadMatrix(save_matrix); + } break; + + case DrawImage: + { + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgGetMatrix(save_matrix); + VGfloat imagewidth = vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH); + VGfloat imageheight = vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT); + + + //vgScale(command.w,command.h); + + if (command.reference) //special behaviout for bw images they act as a mask on the current paint + { + vgTranslate(command.x, command.y); + vgSetPaint((VGPaint) command.reference, VG_FILL_PATH); + vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH); + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); + vgScale(aspect_correction, 1.f); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + vgGetMatrix(save_matrix2); + vgScale(imagewidth, imageheight); + } + else + { + + //vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT)); + float scalex = command.w / imagewidth; + float scaley = command.h / imageheight; + float tx = command.x; + float ty = command.y; + + if (command.corner == TopLeftLimited) + { + if (scalex != 0.f && scaley != 0.f) + { + float imageaspect = imagewidth / imageheight; + float boxaspect = command.w / command.h / aspect_correction; + + if (imageaspect > boxaspect) + { + scaley = 0.f; + ty += (command.h - imageheight * scalex / aspect_correction) * 0.5f; + } + else + { + scalex = 0.f; + tx += (command.w - imagewidth * scaley * aspect_correction) * 0.5f; + } + + } + + } + + if (scalex == 0.f && scaley == 0.f) + { + scalex = aspect_correction; + scaley = 1.f; + } + else if (scalex == 0.f) + { + scalex = scaley * aspect_correction; + } + else if (scaley == 0.f) + { + scaley = scalex / aspect_correction; + } + + + if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle) + { + ty -= imageheight * scaley; + } + + if (command.corner == BottomRight || command.corner == TopRight) + { + tx -= imagewidth * scalex; + } + + if (command.corner == BottomMiddle || command.corner == TopMiddle) + { + tx -= imagewidth * scalex * 0.5f; + } + + vgTranslate(tx, ty); + //vgScale(command.w/imagewidth,command.h/imageheight); + vgScale(scalex, scaley); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL); + //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Scale %g %g %g %g %g %g",command.w,imagewidth,command.h,imageheight,scalex,scaley); + } + + + //vgLoadIdentity(); + //vgTranslate(200.f,500.f); + //vgScale(100.f,100.f); + + vgDrawImage((VGImage) command.target.image); + + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Image %d %x %g %g %g %g %x",command.reference,command.target.image,command.x,command.y,command.w,command.h, + // vgGetError()); + if (command.reference) + { + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + vgLoadMatrix(save_matrix2); + } + + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgLoadMatrix(save_matrix); + } break; + + case DrawGlyph: + { + vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); + vgGetMatrix(save_matrix); + vgSetPaint((VGPaint) command.reference, VG_FILL_PATH); + vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH); + vgTranslate(command.x, command.y); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + vgGetMatrix(save_matrix2); + unsigned int glyph_index = FT_Get_Char_Index(ft_face, command.target.textchar); + vgScale(font_exp_x[glyph_index], font_height); + + + VGfloat gori[] = {0., 0.}; + vgSetfv(VG_GLYPH_ORIGIN, 2, gori); + + + vgDrawGlyph(vgfont, glyph_index, VG_FILL_PATH, VG_FALSE); + //vgDrawPath(std_paths[Rectangle],VG_FILL_PATH); + /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw Glyph %d %c %d %g %g %x",command.reference,command.target.textchar,glyph_index,command.x,command.y, + vgGetError());*/ + vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); + vgLoadMatrix(save_matrix); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + vgLoadMatrix(save_matrix2); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + } break; + + case DrawTTchar: + { + cTeletextChar tchar; + tchar.setInternal(command.target.ttchar); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); + vgGetMatrix(save_matrix); + enumTeletextColor ttforegcolour = tchar.GetFGColor(); + enumTeletextColor ttbackgcolour = tchar.GetBGColor(); + + if (tchar.GetBoxedOut()) + { + ttforegcolour = ttcTransparent; + ttbackgcolour = ttcTransparent; + } + + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); + + + vgTranslate(command.x + command.w * 11.85f * 1.4f, command.y + command.h * 19.75f); + VGfloat gori[] = {0., 0.}; + vgSetfv(VG_GLYPH_ORIGIN, 2, gori); + + vgScale(-1.4f, 2.f); + unsigned int color = Surface::enumTeletextColorToCoulour(ttbackgcolour).rgba(); + color = color << 8 | (color & 0xff000000) >> 24; + vgSetColor(vgttpaint, color); + vgSetPaint((VGPaint) vgttpaint, VG_FILL_PATH); + vgSetPaint((VGPaint) vgttpaint, VG_STROKE_PATH); + cTeletextChar filled; + filled.setInternal(0x187f); + unsigned int glyph_index = loadTTchar(filled); + vgDrawGlyph(vgttfont, glyph_index, VG_FILL_PATH, VG_FALSE); + + color = Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(); + color = color << 8 | (color & 0xff000000) >> 24; + vgSetColor(vgttpaint, color); + vgSetPaint((VGPaint) vgttpaint, VG_FILL_PATH); + vgSetPaint((VGPaint) vgttpaint, VG_STROKE_PATH); + glyph_index = loadTTchar(tchar); + vgDrawGlyph(vgttfont, glyph_index, VG_FILL_PATH, VG_FALSE); + + /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw TTchar %x %x %x %x",glyph_index,ttforegcolour,Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(), + vgGetColor(vgttpaint));*/ + + + vgLoadMatrix(save_matrix); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); + + } break; + + case DrawClipping: + { + VGint coords[4] = {0, 0, 0, 0}; + coords[0] = ((command.x + clip_shift_x) * ((float)BACKBUFFER_WIDTH) / 720.f); + coords[1] = ((576.f - command.y - clip_shift_y - command.h) * ((float)BACKBUFFER_HEIGHT) / 576.f); + coords[2] = ((command.w - 1.f) * ((float)BACKBUFFER_WIDTH) / 720.f); + coords[3] = ((command.h - 1.f) * ((float)BACKBUFFER_HEIGHT) / 576.f); + vgSetiv(VG_SCISSOR_RECTS, 4, coords); + + if (command.w == 0.f && command.h == 0.f) + vgSeti(VG_SCISSORING, VG_FALSE); + else vgSeti(VG_SCISSORING, VG_TRUE); + } break; + + case DrawImageLoading: + case DrawNoop: + {} + } } //int imcount=0;// this is debug code and should not go into release unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) { - switch (command.task){ - case OVGreplacefont: { - vgDestroyFont(vgfont); - loadFont(true); - return 0; - } break; - - case OVGdestroyImageRef: {//imcount--; - //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount); - vgDestroyImage((VGImage)command.param1); - return 0; - } break; - case OVGdestroyPaint: { - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint Destroy %d ",command.param1); - vgDestroyPaint((VGPaint)command.param1); - return 0; - } break; - case OVGcreateImagePalette: {//imcount++; - VGImage input=vgCreateImage(VG_A_8,command.param1, command.param2, - VG_IMAGE_QUALITY_NONANTIALIASED| - VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create palette %d %d %x %d",command.param1,command.param2,vgGetError(),input); - vgImageSubData(input,command.data,command.param1, - VG_A_8,0,0,command.param1, command.param2); // upload palettized image data - VGImage handle=vgCreateImage(VG_sRGBA_8888,command.param1, command.param2, - VG_IMAGE_QUALITY_NONANTIALIASED| - VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER); - VGuint *palette=(VGuint*)malloc(256*sizeof(VGuint)); - VGuint *in_palette=(VGuint*)command.data2; - for (int i=0;i<256;i++) { - VGuint color=in_palette[i]; - palette[i]=color<<8 | (color &0xff000000)>>24; - } - - vgLookupSingle(handle,input,palette,VG_ALPHA,VG_FALSE,VG_FALSE); - free(palette); - vgDestroyImage(input); - - return handle; - } break; - case OVGcreateMonoBitmap: {//imcount++; - VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2, - VG_IMAGE_QUALITY_FASTER); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle); - unsigned int buffer_len=(command.param1*command.param2)>>3; - unsigned char * buffer=(unsigned char*)malloc(buffer_len); - unsigned char * r_buffer1=buffer; - const unsigned char* r_buffer2= static_cast(command.data); - unsigned char *buffer_end=buffer+buffer_len; - while (r_buffer1!=buffer_end) { - unsigned char byte=*r_buffer2; - *r_buffer1=((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; - r_buffer1++;r_buffer2++; - } - - - vgImageSubData(handle,buffer,command.param1>>3, - VG_A_1,0,0,command.param1, command.param2); - free(buffer); - // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono2 %d %d %x %d",command.param1,command.param2,vgGetError(),handle); - return handle; - } break; - /*case OVGcreateImageFile: { - VGImage handle; - try{ - Image *imagefile=(Image*)command.data; - Blob imageblob; - imagefile->write(&imageblob,"RGBA"); - - - handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(), - VG_IMAGE_QUALITY_BETTER); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data()); - vgImageSubData(handle,imageblob.data(),imagefile->columns()*4, - VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows()); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data()); - delete imagefile; - }catch( Exception &error_ ) - { - Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick hT: %s",error_.what()); - - return 0; - } - - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file %d %d %x %d",command.param1,command.param2,vgGetError(),handle); - return handle; - } break;*/ - case OVGcreateImageMemory: {//imcount++; - PictureInfo *info = (PictureInfo*) command.data; - VGImage handle; - //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d",imcount); - handle=vgCreateImage(VG_sABGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER); - vgImageSubData(handle,info->image,info->width*4, - VG_sABGR_8888,0,0,info->width,info->height); - info->decoder->freeReference(info->reference); - - bool static_image=true; - if (info->lindex & 0xffffffff) static_image=false; - - Message* m = new Message(); - // We have a pictures! send a message to ourself, to switch to gui thread - m->from=this; - m->p_to = Message::CONTROL; - m->data = reinterpret_cast(handle); - if (!static_image) { - m->message=Message::NEW_PICTURE; - m->tag = info->lindex; - } else { - m->message=Message::NEW_PICTURE_STATIC; - m->tag = info->lindex>> 32LL; - } - MessageQueue::getInstance()->postMessage(m); // inform command about new picture - - delete info; - - } break; - case OVGcreateEGLImage: {//imcount++; - PictureInfo *info = (PictureInfo*) command.data; - VGImage handle; - - handle=vgCreateImage(VG_sABGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER); -// Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x %d",info->width,info->height, handle,imcount); - - info->handle = handle; - info->reference = eglCreateImageKHR(egl_display, egl_context, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)handle, NULL); - if (info->reference) return true; - else { - Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x Fail!",info->width,info->height, handle); - if (handle) vgDestroyImage(handle); - return false; - } - - } break; - - case OVGreadyEGLImage: { - PictureInfo *info = (PictureInfo*) command.data; - eglDestroyImageKHR(egl_display,info->reference); - bool static_image=true; - if (info->lindex & 0xffffffff) static_image=false; - Message* m = new Message(); - m->from=this; - m->p_to = Message::CONTROL; - m->data = reinterpret_cast(info->handle); - if (!static_image) { - m->message=Message::NEW_PICTURE; - m->tag = info->lindex; - } else { - m->message=Message::NEW_PICTURE_STATIC; - m->tag = info->lindex>> 32LL; - } - MessageQueue::getInstance()->postMessage(m); // inform command about new picture - - delete info; - } break; - - - - case OVGcreateColorRef :{ - VGPaint handle; - handle=vgCreatePaint(); - DrawStyle *style=(DrawStyle*)command.data; - switch (style->ft) { - case DrawStyle::Color: { - vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); - vgSetColor(handle,command.param1); - //VGuint rgba; - //rgba = vgGetColor((VGPaint)handle); - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint %d %x %x",handle,command.param1,rgba); - } break; - case DrawStyle::GradientLinear: { - vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT); - VGfloat params[]={style->x1,style->y1,style->x2,style->y2,style->r}; - //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Gradient %d %g %g %g %g",handle,params[0],params[1],params[2],params[3]); - vgSetParameterfv(handle,VG_PAINT_LINEAR_GRADIENT,4,params); - - - - } break; - case DrawStyle::GradientRadial: { - vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT); - VGfloat params[]={style->x1,style->y1,style->x2,style->y2,style->r}; - vgSetParameterfv(handle,VG_PAINT_RADIAL_GRADIENT,5,params); - - - - } break; - }; - if (style->ft==DrawStyle::GradientLinear ||style->ft==DrawStyle::GradientRadial) { - VGfloat colorramp[5*5]; - colorramp[0+0*5]=0.f; - colorramp[1+0*5]=((float)style->red)/255.f; - colorramp[2+0*5]=((float)style->green)/255.f; - colorramp[3+0*5]=((float)style->blue)/255.f; - colorramp[4+0*5]=((float)style->alpha)/255.f; - for (int i=0;i<(style->num_colors-1);i++) { - colorramp[0+(i+1)*5]=style->grad_pos[i]; - colorramp[1+(i+1)*5]=((float)style->grad_col[i].red)/255.f; - colorramp[2+(i+1)*5]=((float)style->grad_col[i].green)/255.f; - colorramp[3+(i+1)*5]=((float)style->grad_col[i].blue)/255.f; - colorramp[4+(i+1)*5]=((float)style->grad_col[i].alpha)/255.f; - } - colorramp[0+(style->num_colors)*5]=1.f; - colorramp[1+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].red)/255.f; - colorramp[2+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].green)/255.f; - colorramp[3+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].blue)/255.f; - colorramp[4+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].alpha)/255.f; - vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_SPREAD_MODE,VG_COLOR_RAMP_SPREAD_REFLECT); - vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_PREMULTIPLIED,VG_FALSE); - vgSetParameterfv(handle,VG_PAINT_COLOR_RAMP_STOPS,5+(style->num_colors)*5,colorramp); - } - - return handle; - } break; - - - case OVGimageUploadLine: - {} + switch (command.task) + { + case OVGreplacefont: + { + vgDestroyFont(vgfont); + loadFont(true); + return 0; + } break; + + case OVGdestroyImageRef: //imcount--; + { + //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount); + vgDestroyImage((VGImage)command.param1); + return 0; + } break; + + case OVGdestroyPaint: + { + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint Destroy %d ",command.param1); + vgDestroyPaint((VGPaint)command.param1); + return 0; + } break; + + case OVGcreateImagePalette: //imcount++; + { + VGImage input = vgCreateImage(VG_A_8, command.param1, command.param2, + VG_IMAGE_QUALITY_NONANTIALIASED | + VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create palette %d %d %x %d",command.param1,command.param2,vgGetError(),input); + vgImageSubData(input, command.data, command.param1, + VG_A_8, 0, 0, command.param1, command.param2); // upload palettized image data + VGImage handle = vgCreateImage(VG_sRGBA_8888, command.param1, command.param2, + VG_IMAGE_QUALITY_NONANTIALIASED | + VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER); + VGuint* palette = (VGuint*)malloc(256 * sizeof(VGuint)); + VGuint* in_palette = (VGuint*)command.data2; + + for (int i = 0; i < 256; i++) + { + VGuint color = in_palette[i]; + palette[i] = color << 8 | (color & 0xff000000) >> 24; + } + + vgLookupSingle(handle, input, palette, VG_ALPHA, VG_FALSE, VG_FALSE); + free(palette); + vgDestroyImage(input); + + return handle; + } break; + + case OVGcreateMonoBitmap: //imcount++; + { + VGImage handle = vgCreateImage(VG_A_1, command.param1, command.param2, + VG_IMAGE_QUALITY_FASTER); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle); + unsigned int buffer_len = (command.param1 * command.param2) >> 3; + unsigned char* buffer = (unsigned char*)malloc(buffer_len); + unsigned char* r_buffer1 = buffer; + const unsigned char* r_buffer2 = static_cast(command.data); + unsigned char* buffer_end = buffer + buffer_len; + + while (r_buffer1 != buffer_end) + { + unsigned char byte = *r_buffer2; + *r_buffer1 = ((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; + r_buffer1++; r_buffer2++; + } + + + vgImageSubData(handle, buffer, command.param1 >> 3, + VG_A_1, 0, 0, command.param1, command.param2); + free(buffer); + // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono2 %d %d %x %d",command.param1,command.param2,vgGetError(),handle); + return handle; + } break; + + /*case OVGcreateImageFile: { + VGImage handle; + try{ + Image *imagefile=(Image*)command.data; + Blob imageblob; + imagefile->write(&imageblob,"RGBA"); + + + handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(), + VG_IMAGE_QUALITY_BETTER); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data()); + vgImageSubData(handle,imageblob.data(),imagefile->columns()*4, + VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows()); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data()); + delete imagefile; + }catch( Exception &error_ ) + { + Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick hT: %s",error_.what()); + + return 0; + } + + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file %d %d %x %d",command.param1,command.param2,vgGetError(),handle); + return handle; + } break;*/ + case OVGcreateImageMemory: //imcount++; + { + PictureInfo* info = (PictureInfo*) command.data; + VGImage handle; + //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d",imcount); + handle = vgCreateImage(VG_sABGR_8888, info->width, info->height, VG_IMAGE_QUALITY_BETTER); + vgImageSubData(handle, info->image, info->width * 4, + VG_sABGR_8888, 0, 0, info->width, info->height); + info->decoder->freeReference(info->reference); + + bool static_image = true; + + if (info->lindex & 0xffffffff) static_image = false; + + Message* m = new Message(); + // We have a pictures! send a message to ourself, to switch to gui thread + m->from = this; + m->p_to = Message::CONTROL; + m->data = reinterpret_cast(handle); + + if (!static_image) + { + m->message = Message::NEW_PICTURE; + m->tag = info->lindex; + } + else + { + m->message = Message::NEW_PICTURE_STATIC; + m->tag = info->lindex >> 32LL; + } + + MessageQueue::getInstance()->postMessage(m); // inform command about new picture + + delete info; + + } break; + + case OVGcreateEGLImage: //imcount++; + { + PictureInfo* info = (PictureInfo*) command.data; + VGImage handle; + + handle = vgCreateImage(VG_sABGR_8888, info->width, info->height, VG_IMAGE_QUALITY_BETTER); + // Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x %d",info->width,info->height, handle,imcount); + + info->handle = handle; + info->reference = eglCreateImageKHR(egl_display, egl_context, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)handle, NULL); + + if (info->reference) return true; + else + { + Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x Fail!", info->width, info->height, handle); + + if (handle) vgDestroyImage(handle); + + return false; + } + + } break; + + case OVGreadyEGLImage: + { + PictureInfo* info = (PictureInfo*) command.data; + eglDestroyImageKHR(egl_display, info->reference); + bool static_image = true; + + if (info->lindex & 0xffffffff) static_image = false; + + Message* m = new Message(); + m->from = this; + m->p_to = Message::CONTROL; + m->data = reinterpret_cast(info->handle); + + if (!static_image) + { + m->message = Message::NEW_PICTURE; + m->tag = info->lindex; + } + else + { + m->message = Message::NEW_PICTURE_STATIC; + m->tag = info->lindex >> 32LL; + } + + MessageQueue::getInstance()->postMessage(m); // inform command about new picture + + delete info; + } break; + + + + case OVGcreateColorRef : + { + VGPaint handle; + handle = vgCreatePaint(); + DrawStyle* style = (DrawStyle*)command.data; + + switch (style->ft) + { + case DrawStyle::Color: + { + vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetColor(handle, command.param1); + //VGuint rgba; + //rgba = vgGetColor((VGPaint)handle); + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint %d %x %x",handle,command.param1,rgba); + } break; + + case DrawStyle::GradientLinear: + { + vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT); + VGfloat params[] = {style->x1, style->y1, style->x2, style->y2, style->r}; + //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Gradient %d %g %g %g %g",handle,params[0],params[1],params[2],params[3]); + vgSetParameterfv(handle, VG_PAINT_LINEAR_GRADIENT, 4, params); + + + + } break; + + case DrawStyle::GradientRadial: + { + vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT); + VGfloat params[] = {style->x1, style->y1, style->x2, style->y2, style->r}; + vgSetParameterfv(handle, VG_PAINT_RADIAL_GRADIENT, 5, params); - } - return 0; + + } break; + }; + + if (style->ft == DrawStyle::GradientLinear || style->ft == DrawStyle::GradientRadial) + { + VGfloat colorramp[5 * 5]; + colorramp[0 + 0 * 5] = 0.f; + colorramp[1 + 0 * 5] = ((float)style->red) / 255.f; + colorramp[2 + 0 * 5] = ((float)style->green) / 255.f; + colorramp[3 + 0 * 5] = ((float)style->blue) / 255.f; + colorramp[4 + 0 * 5] = ((float)style->alpha) / 255.f; + + for (int i = 0; i < (style->num_colors - 1); i++) + { + colorramp[0 + (i + 1) * 5] = style->grad_pos[i]; + colorramp[1 + (i + 1) * 5] = ((float)style->grad_col[i].red) / 255.f; + colorramp[2 + (i + 1) * 5] = ((float)style->grad_col[i].green) / 255.f; + colorramp[3 + (i + 1) * 5] = ((float)style->grad_col[i].blue) / 255.f; + colorramp[4 + (i + 1) * 5] = ((float)style->grad_col[i].alpha) / 255.f; + } + + colorramp[0 + (style->num_colors) * 5] = 1.f; + colorramp[1 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].red) / 255.f; + colorramp[2 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].green) / 255.f; + colorramp[3 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].blue) / 255.f; + colorramp[4 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].alpha) / 255.f; + vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_REFLECT); + vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, VG_FALSE); + vgSetParameterfv(handle, VG_PAINT_COLOR_RAMP_STOPS, 5 + (style->num_colors) * 5, colorramp); + } + + return handle; + } break; + + + case OVGimageUploadLine: + {} + + } + + return 0; } bool OsdOpenVG::processTasks() { - bool worked=false; - taskmutex.lock(); - vgmutex.lock(); - while (vgcommands.size()>0) - { - OpenVGCommand comm=vgcommands.front(); - vgcommands.pop_front(); - taskmutex.unlock(); - - OpenVGResponse resp; - resp.result=handleTask(comm); - resp.id=comm.id; - taskmutex.lock(); - if (comm.id) { - vgresponses.push_back(resp); - } - taskmutex.unlock(); - vgmutex.unlock(); - //threadCheckExit(); - - /* Getting rid of Signal class. As with VideoOMX, just replicate what Signal did here - * and figure out if any of this can be simplified later. e.g. taskmutex sounds - * like it should be the mutex being used. 3 mutexes here??? - */ - - vgTaskSignalMutex.lock(); - vgTaskSignal.notify_one(); - vgTaskSignalMutex.unlock(); - - taskmutex.lock(); - vgmutex.lock(); - worked=true; - } - taskmutex.unlock(); - vgmutex.unlock(); + bool worked = false; + taskmutex.lock(); + vgmutex.lock(); + + while (vgcommands.size() > 0) + { + OpenVGCommand comm = vgcommands.front(); + vgcommands.pop_front(); + taskmutex.unlock(); + + OpenVGResponse resp; + resp.result = handleTask(comm); + resp.id = comm.id; + taskmutex.lock(); + + if (comm.id) + { + vgresponses.push_back(resp); + } + + taskmutex.unlock(); + vgmutex.unlock(); + //threadCheckExit(); + + /* Getting rid of Signal class. As with VideoOMX, just replicate what Signal did here + * and figure out if any of this can be simplified later. e.g. taskmutex sounds + * like it should be the mutex being used. 3 mutexes here??? + */ + + vgTaskSignalMutex.lock(); + vgTaskSignal.notify_one(); + vgTaskSignalMutex.unlock(); - return worked; + taskmutex.lock(); + vgmutex.lock(); + worked = true; + } + + taskmutex.unlock(); + vgmutex.unlock(); + + return worked; } -bool OsdOpenVG::haveOpenVGResponse(unsigned int id,unsigned int * resp) +bool OsdOpenVG::haveOpenVGResponse(unsigned int id, unsigned int* resp) { - taskmutex.lock(); - if (vgresponses.size()>0) - { - std::deque::iterator itty=vgresponses.begin(); - while (itty!=vgresponses.end()) - { - if ((*itty).id==id) { - *resp=(*itty).result; - taskmutex.unlock(); - return true; - } - itty++; - } - } - taskmutex.unlock(); - return false; + taskmutex.lock(); + + if (vgresponses.size() > 0) + { + std::deque::iterator itty = vgresponses.begin(); + + while (itty != vgresponses.end()) + { + if ((*itty).id == id) + { + *resp = (*itty).result; + taskmutex.unlock(); + return true; + } + + itty++; + } + } + + taskmutex.unlock(); + return false; } -unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm,bool wait) +unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm, bool wait) { - taskmutex.lock(); - if (wait){ - comm.id=wait_id; - wait_id++; - } else { - comm.id=0; // we are not waiting - } - vgcommands.push_back(comm); - taskmutex.unlock(); - threadSignal(); - while (wait) { - unsigned int resp; - if (!haveOpenVGResponse(comm.id,&resp)) { - -// Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand wait_for"); - std::unique_lock ul(vgTaskSignalMutex); - /*auto a = */ vgTaskSignal.wait_for(ul, std::chrono::milliseconds(100)); - ul.unlock(); -/* - if (a == std::cv_status::timeout) - Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand timeout"); - else - Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand no timeout"); -*/ - /* - struct timespec target_time; - clock_gettime(CLOCK_REALTIME,&target_time); - target_time.tv_nsec+=1000000LL*100; - if (target_time.tv_nsec>999999999) { - target_time.tv_nsec-=1000000000L; - target_time.tv_sec+=1; - } - vgtaskSignal.waitForSignalTimed(&target_time); - */ - - - } else { - return resp; - } - } - return 0; + taskmutex.lock(); + + if (wait) + { + comm.id = wait_id; + wait_id++; + } + else + { + comm.id = 0; // we are not waiting + } + + vgcommands.push_back(comm); + taskmutex.unlock(); + threadSignal(); + + while (wait) + { + unsigned int resp; + + if (!haveOpenVGResponse(comm.id, &resp)) + { + + // Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand wait_for"); + std::unique_lock ul(vgTaskSignalMutex); + /*auto a = */ vgTaskSignal.wait_for(ul, std::chrono::milliseconds(100)); + ul.unlock(); + /* + if (a == std::cv_status::timeout) + Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand timeout"); + else + Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand no timeout"); + */ + /* + struct timespec target_time; + clock_gettime(CLOCK_REALTIME,&target_time); + target_time.tv_nsec+=1000000LL*100; + if (target_time.tv_nsec>999999999) { + target_time.tv_nsec-=1000000000L; + target_time.tv_sec+=1; + } + vgtaskSignal.waitForSignalTimed(&target_time); + */ + + + } + else + { + return resp; + } + } + + return 0; } void OsdOpenVG::destroyImageRef(ImageIndex index) { - struct OpenVGCommand comm; - comm.task=OVGdestroyImageRef; - comm.param1=index; - putOpenVGCommand(comm,false); + struct OpenVGCommand comm; + comm.task = OVGdestroyImageRef; + comm.param1 = index; + putOpenVGCommand(comm, false); } -bool OsdOpenVG::getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length) +bool OsdOpenVG::getStaticImageData(unsigned int static_id, UCHAR** userdata, ULONG* length) { - if (sa_MAX>static_id) { - *userdata = static_artwork_begin[static_id]; - *length = static_artwork_end[static_id] - static_artwork_begin[static_id]; - return true; - } + if (sa_MAX > static_id) + { + *userdata = static_artwork_begin[static_id]; + *length = static_artwork_end[static_id] - static_artwork_begin[static_id]; + return true; + } - *userdata = NULL; - *length = 0; - return false; + *userdata = NULL; + *length = 0; + return false; } void OsdOpenVG::createPicture(struct PictureInfo& pict_inf) { - struct OpenVGCommand comm; - Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "TVMedia Create Picture %d",pict_inf.type); - if (pict_inf.type == PictureInfo::RGBAMemBlock) { - comm.task = OVGcreateImageMemory; - comm.data = new PictureInfo(pict_inf); - putOpenVGCommand(comm,false); - } else if (pict_inf.type == PictureInfo::EGLImage) { - comm.task = OVGreadyEGLImage; - comm.data = new PictureInfo(pict_inf); - putOpenVGCommand(comm,false); - } else { - // unsupported - pict_inf.decoder->freeReference(pict_inf.reference); + struct OpenVGCommand comm; + Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "TVMedia Create Picture %d", pict_inf.type); + if (pict_inf.type == PictureInfo::RGBAMemBlock) + { + comm.task = OVGcreateImageMemory; + comm.data = new PictureInfo(pict_inf); + putOpenVGCommand(comm, false); + } + else if (pict_inf.type == PictureInfo::EGLImage) + { + comm.task = OVGreadyEGLImage; + comm.data = new PictureInfo(pict_inf); + putOpenVGCommand(comm, false); + } + else + { + // unsupported + pict_inf.decoder->freeReference(pict_inf.reference); - } + + } } -bool OsdOpenVG::getEGLPicture(struct OsdVector::PictureInfo & info , EGLDisplay * display) +bool OsdOpenVG::getEGLPicture(struct OsdVector::PictureInfo& info, EGLDisplay* display) { - struct OpenVGCommand comm; - info.type = PictureInfo::EGLImage; - comm.task = OVGcreateEGLImage; - comm.data = &info; - *display = egl_display; - return putOpenVGCommand(comm,true); + struct OpenVGCommand comm; + info.type = PictureInfo::EGLImage; + comm.task = OVGcreateEGLImage; + comm.data = &info; + *display = egl_display; + return putOpenVGCommand(comm, true); } -ImageIndex OsdOpenVG::createMonoBitmap(void *base,int width,int height) +ImageIndex OsdOpenVG::createMonoBitmap(void* base, int width, int height) { - struct OpenVGCommand comm; - comm.task=OVGcreateMonoBitmap; - comm.param1=width; - comm.param2=height; - comm.data=base; - return putOpenVGCommand(comm,true); + struct OpenVGCommand comm; + comm.task = OVGcreateMonoBitmap; + comm.param1 = width; + comm.param2 = height; + comm.data = base; + return putOpenVGCommand(comm, true); } -ImageIndex OsdOpenVG::createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data) +ImageIndex OsdOpenVG::createImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data) { - struct OpenVGCommand comm; - comm.task=OVGcreateImagePalette; - comm.param1=width; - comm.param2=height; - comm.data=image_data; - comm.data2=palette_data; - return putOpenVGCommand(comm,true); + struct OpenVGCommand comm; + comm.task = OVGcreateImagePalette; + comm.param1 = width; + comm.param2 = height; + comm.data = image_data; + comm.data2 = palette_data; + return putOpenVGCommand(comm, true); } void OsdOpenVG::destroyStyleRef(VectorHandle index) { - struct OpenVGCommand comm; - comm.task=OVGdestroyPaint; - comm.param1=index; - putOpenVGCommand(comm,false); + struct OpenVGCommand comm; + comm.task = OVGdestroyPaint; + comm.param1 = index; + putOpenVGCommand(comm, false); } -VectorHandle OsdOpenVG::createStyleRef(const DrawStyle &c) +VectorHandle OsdOpenVG::createStyleRef(const DrawStyle& 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); + 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 49e81ac..f62c628 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -38,7 +38,7 @@ #include "videoomx.h" #include "staticartwork.h" #ifdef PICTURE_DECODER_OMX -#include "imageomx.h" + #include "imageomx.h" #endif #include @@ -46,38 +46,40 @@ #include #include FT_FREETYPE_H -enum OpenVGTask { - OVGdestroyImageRef, - OVGdestroyPaint, - OVGcreateImagePalette, - OVGcreateMonoBitmap, - OVGcreateColorRef, - OVGimageUploadLine, - //OVGcreateImageFile, - OVGreplacefont, - OVGcreateImageMemory, - OVGcreateEGLImage, - OVGreadyEGLImage +enum OpenVGTask +{ + OVGdestroyImageRef, + OVGdestroyPaint, + OVGcreateImagePalette, + OVGcreateMonoBitmap, + OVGcreateColorRef, + OVGimageUploadLine, + //OVGcreateImageFile, + OVGreplacefont, + OVGcreateImageMemory, + OVGcreateEGLImage, + OVGreadyEGLImage }; struct OpenVGCommand { - enum OpenVGTask task; - const void *data; - const void *data2; - unsigned int param1,param2,param3; - unsigned int id; //only set an id if you are waiting + enum OpenVGTask task; + const void* data; + const void* data2; + unsigned int param1, param2, param3; + unsigned int id; //only set an id if you are waiting }; -struct OpenVGResponse{ - unsigned int id; - unsigned int result; +struct OpenVGResponse +{ + unsigned int id; + unsigned int result; }; class OsdOpenVG : public OsdVector, public Thread_TYPE #ifdef PICTURE_DECODER_OMX - , public EGLPictureCreator + , public EGLPictureCreator #endif { public: @@ -88,47 +90,47 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE int shutdown(); int stopUpdate(); - bool screenShot(void *buffer, int width, int height, bool osd /*include osd*/); + bool screenShot(void* buffer, int width, int height, bool osd /*include osd*/); float getFontHeight(); float getCharWidth(wchar_t c); - int getFontNames(const char *** names,const char *** names_keys); + int getFontNames(const char*** names, const char*** names_keys); - virtual void setFont(const char * fontname); + virtual void setFont(const char* fontname); virtual float getPixelAspect() {return aspect_correction;}; - bool getEGLPicture(struct OsdVector::PictureInfo & info, EGLDisplay * display); + bool getEGLPicture(struct OsdVector::PictureInfo& info, EGLDisplay* display); void updateBackgroundColor(DrawStyle bg); -protected: + protected: - /*osd vector implementation*/ + /*osd vector implementation*/ void destroyImageRef(ImageIndex index); - // ImageIndex createJpeg(const char* fileName, int *width,int *height); - ImageIndex createMonoBitmap(void *base,int width,int height); - ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data); + // ImageIndex createJpeg(const char* fileName, int *width,int *height); + ImageIndex createMonoBitmap(void* base, int width, int height); + ImageIndex createImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data); void createPicture(struct PictureInfo& pict_inf); void destroyStyleRef(VectorHandle index); - VectorHandle createStyleRef(const DrawStyle &c); - bool getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length); + VectorHandle createStyleRef(const DrawStyle& c); + bool getStaticImageData(unsigned int static_id, UCHAR** userdata, ULONG* length); - void drawSetTrans(SurfaceCommands & sc); - void executeDrawCommand(SVGCommand & command); + void drawSetTrans(SurfaceCommands& sc); + void executeDrawCommand(SVGCommand& command); void initPaths(); void destroyPaths(); - VGPath std_paths[PIPoint+1]; + VGPath std_paths[PIPoint + 1]; long long lastrendertime; void InternalRendering(); - void getScreenSize(int &width, int &height); - void getRealScreenSize(int &width, int &height); + void getScreenSize(int& width, int& height); + void getRealScreenSize(int& width, int& height); @@ -141,8 +143,8 @@ protected: std::deque vgcommands; std::deque vgresponses; bool processTasks(); - bool haveOpenVGResponse(unsigned int id,unsigned int * resp); - unsigned int putOpenVGCommand(OpenVGCommand& comm,bool wait); + bool haveOpenVGResponse(unsigned int id, unsigned int* resp); + unsigned int putOpenVGCommand(OpenVGCommand& comm, bool wait); unsigned int handleTask(OpenVGCommand& command); //void purgeAllReferences(); unsigned int wait_id; @@ -153,7 +155,7 @@ protected: VGFont vgttfont; VGPaint vgttpaint; int loadFont(bool fontchange); - std::map font_exp_x; + std::map font_exp_x; std::vector fontnames; std::vector fontnames_keys; char* cur_fontname; @@ -162,7 +164,7 @@ protected: int clip_shift_y; unsigned int loadTTchar(cTeletextChar c); - std::map tt_font_chars; + std::map tt_font_chars; void threadMethod(); @@ -179,19 +181,19 @@ protected: uint32_t mode; - EGLDisplay egl_display; - EGLSurface egl_surface; - EGLContext egl_context; - EGLConfig egl_ourconfig; - float font_height; - float aspect_correction; - bool freetype_inited; + EGLDisplay egl_display; + EGLSurface egl_surface; + EGLContext egl_context; + EGLConfig egl_ourconfig; + float font_height; + float aspect_correction; + bool freetype_inited; - uint8_t *static_artwork_begin[sa_MAX]; - uint8_t *static_artwork_end[sa_MAX]; + uint8_t* static_artwork_begin[sa_MAX]; + uint8_t* static_artwork_end[sa_MAX]; #ifdef PICTURE_DECODER_OMX - ImageOMX *imageomx; + ImageOMX* imageomx; #endif }; diff --git a/osdvector.cc b/osdvector.cc index c09bba4..e1eb845 100644 --- a/osdvector.cc +++ b/osdvector.cc @@ -30,73 +30,81 @@ #define MAGICKCORE_HDRI_ENABLE 0 #include -using namespace Magick; +using namespace Magick; -class MagickDecoder: public OsdVector::PictureDecoder { -public: - MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;}; +class MagickDecoder: public OsdVector::PictureDecoder +{ + public: + MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid = false;}; - unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem); + unsigned char* decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem); bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf); - void freeReference(void * ref); + void freeReference(void* ref); -protected: + protected: OsdVector::PictureInfo pictInf; - bool pictInfValid; + bool pictInfValid; }; -unsigned char * MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem) +unsigned char* MagickDecoder::decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem) { - if (pictInfValid) return buffer; // does support only one image at a Time; - Image magicimage; - Blob *imageblob = new Blob(); - Blob myblob; - try{ - Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture"); + if (pictInfValid) return buffer; // does support only one image at a Time; - if (freemem) myblob.updateNoCopy(buffer,length,Blob::MallocAllocator); - else myblob.update(buffer,length); - magicimage.read(myblob); + Image magicimage; + Blob* imageblob = new Blob(); + Blob myblob; - magicimage.write(imageblob,"RGBA"); + try + { + Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture"); - }catch( Exception &error_ ) - { - Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what()); - delete imageblob; - Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2"); - unsigned char* newbuffer=(unsigned char*) malloc(length); - memcpy(newbuffer,myblob.data(),length); - return newbuffer; - } - pictInf.reference = (void*) imageblob; - pictInf.width = magicimage.columns(); - pictInf.height = magicimage.rows(); - pictInf.image = imageblob->data(); - pictInf.decoder = this; - pictInf.type = OsdVector::PictureInfo::RGBAMemBlock; - pictInf.lindex = index; - pictInfValid = true; + if (freemem) myblob.updateNoCopy(buffer, length, Blob::MallocAllocator); + else myblob.update(buffer, length); + + magicimage.read(myblob); + + magicimage.write(imageblob, "RGBA"); + } + catch ( Exception& error_ ) + { + Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s", error_.what()); + delete imageblob; + Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2"); + unsigned char* newbuffer = (unsigned char*) malloc(length); + memcpy(newbuffer, myblob.data(), length); + return newbuffer; + } + pictInf.reference = (void*) imageblob; + pictInf.width = magicimage.columns(); + pictInf.height = magicimage.rows(); + pictInf.image = imageblob->data(); + pictInf.decoder = this; + pictInf.type = OsdVector::PictureInfo::RGBAMemBlock; + pictInf.lindex = index; + pictInfValid = true; - // I can handle everything, so the return value is always true - return NULL; + + + // I can handle everything, so the return value is always true + return NULL; } -void MagickDecoder::freeReference(void * ref) +void MagickDecoder::freeReference(void* ref) { - Blob *todelete = (Blob*) ref; - delete todelete; + Blob* todelete = (Blob*) ref; + delete todelete; } bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf) { - if (!pictInfValid) return false; - pict_inf=pictInf; - pictInfValid = false; - return true; + if (!pictInfValid) return false; + + pict_inf = pictInf; + pictInfValid = false; + return true; } @@ -104,15 +112,17 @@ bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf) OsdVector::OsdVector() { - setlocale(LC_CTYPE,"C.UTF-8"); + setlocale(LC_CTYPE, "C.UTF-8"); #ifdef PICTURE_DECODER_MAGICK - reader.addDecoder(new MagickDecoder(&reader)); + 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; + for (int i = 0; i < 256; i++) + { + byte_char_width[i] = 0.f; + } + + styles_lastit_valid = styles_ref_lastit_valid = false; } @@ -123,564 +133,721 @@ OsdVector::~OsdVector() int OsdVector::getFD() { - return 0; + return 0; } void OsdVector::screenShot(const char* fileName) { - //Do nothing, if no libmagick is there + //Do nothing, if no libmagick is there #ifdef PICTURE_DECODER_MAGICK - int width,height; - getRealScreenSize(width,height); - size_t length=width*height*4; - void *mem=malloc(length); - - try { - Blob myblob; - if (!screenShot(mem,width,height,true)) { - Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!"); - free(mem); - return; - } - myblob.updateNoCopy(mem,length,Blob::MallocAllocator); - Image image(myblob,Geometry(width,height),8,"RGBA"); - image.write(fileName); - }catch( Exception &error_ ) - { - Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s",error_.what()); - - } + int width, height; + getRealScreenSize(width, height); + size_t length = width * height * 4; + void* mem = malloc(length); + + try + { + Blob myblob; + + if (!screenShot(mem, width, height, true)) + { + Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!"); + free(mem); + return; + } + + myblob.updateNoCopy(mem, length, Blob::MallocAllocator); + Image image(myblob, Geometry(width, height), 8, "RGBA"); + image.write(fileName); + } + catch ( Exception& error_ ) + { + Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what()); + + } #endif } -Surface * OsdVector::createNewSurface() +Surface* OsdVector::createNewSurface() { - return new SurfaceVector(this); + return new SurfaceVector(this); } void OsdVector::Blank() { - // do nothing? remove this one? + // do nothing? remove this one? } int OsdVector::restore() { - // First clear the contents of all registered surfaces - surfaces_mutex.lock(); - - //Now go through all surfaces and draw them - std::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 - images_ref.clear(); - monobitmaps.clear(); - //jpegs.clear(); - styles.clear(); - styles_ref.clear(); - styles_lastit_valid=styles_ref_lastit_valid=false; - palettepics.clear(); - - tvmedias.clear(); - loadindex_ref.clear(); - tvmedias_load.clear(); - tvmedias_load_inv.clear(); - tvmedias_loaded.clear(); - - surfaces_mutex.unlock(); - return 1; + // First clear the contents of all registered surfaces + surfaces_mutex.lock(); + + //Now go through all surfaces and draw them + std::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 + images_ref.clear(); + monobitmaps.clear(); + //jpegs.clear(); + styles.clear(); + styles_ref.clear(); + styles_lastit_valid = styles_ref_lastit_valid = false; + palettepics.clear(); + + tvmedias.clear(); + loadindex_ref.clear(); + tvmedias_load.clear(); + tvmedias_load_inv.clear(); + tvmedias_loaded.clear(); + + surfaces_mutex.unlock(); + return 1; } void OsdVector::drawSurfaces() { - surfaces_mutex.lock(); - std::list todraw; //First figure out if a surfaces is below another surface - std::list::iterator itty1=scommands.begin(); - while (itty1!=scommands.end()) { - std::list::iterator itty2=itty1; - itty2++; - bool hidden=false; - while (itty2!=scommands.end()) { - SurfaceCommands & ref1=*itty1; - SurfaceCommands & ref2=*itty2; - if (ref1.x>=ref2.x && ref1.y>=ref2.y - && (ref1.x+ref1.w) <= (ref2.x+ref2.w) - && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) { - hidden=true; - break; - } - itty2++; - } - if (!hidden) { // we are not hidden, perfect - todraw.push_back(&(*itty1)); - } - itty1++; - } - int swidth,sheight; - getScreenSize(swidth,sheight); - //Now go through all surfaces and draw them - std::list::iterator curdraw=todraw.begin(); - while (curdraw!=todraw.end()) { - drawSetTrans(*(*curdraw)); - 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) { - LoadIndex loadindex=(*commands).target.loadindex; - if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) { - (*commands).instr=DrawImage; - (*commands).target.image=tvmedias_loaded[loadindex];; - incImageRef((*commands).target.image); - removeLoadIndexRef(loadindex); - } - - } - // Now check if the command is on screen! - if (!(*commands).Outside(0,0,swidth,sheight)) { - executeDrawCommand(*commands); - } - commands++; - } - curdraw++; - } + surfaces_mutex.lock(); + std::list todraw; //First figure out if a surfaces is below another surface + std::list::iterator itty1 = scommands.begin(); + + while (itty1 != scommands.end()) + { + std::list::iterator itty2 = itty1; + itty2++; + bool hidden = false; + + while (itty2 != scommands.end()) + { + SurfaceCommands& ref1 = *itty1; + SurfaceCommands& ref2 = *itty2; + + if (ref1.x >= ref2.x && ref1.y >= ref2.y + && (ref1.x + ref1.w) <= (ref2.x + ref2.w) + && (ref1.y + ref1.h) <= (ref2.y + ref2.h) ) + { + hidden = true; + break; + } + + itty2++; + } + + if (!hidden) // we are not hidden, perfect + { + todraw.push_back(&(*itty1)); + } + + itty1++; + } + + int swidth, sheight; + getScreenSize(swidth, sheight); + //Now go through all surfaces and draw them + std::list::iterator curdraw = todraw.begin(); + + while (curdraw != todraw.end()) + { + drawSetTrans(*(*curdraw)); + 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) + { + LoadIndex loadindex = (*commands).target.loadindex; + + if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end()) + { + (*commands).instr = DrawImage; + (*commands).target.image = tvmedias_loaded[loadindex];; + incImageRef((*commands).target.image); + removeLoadIndexRef(loadindex); + } + + } + + // Now check if the command is on screen! + if (!(*commands).Outside(0, 0, swidth, sheight)) + { + executeDrawCommand(*commands); + } + + commands++; + } + + curdraw++; + } + + surfaces_mutex.unlock(); +} - surfaces_mutex.unlock(); +void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width, + std::vector& commands) +{ + surfaces_mutex.lock(); + //First determine it is already in our system + std::list::iterator itty = scommands.begin(); + + while (itty != scommands.end()) + { + if ((*itty).surf == surf) + { + //decrease the references + dereferenceSVGCommand((*itty).commands); + break; + } + + itty++; + } + + // if not insert it + if (itty == scommands.end()) + { + SurfaceCommands new_sc; + new_sc.surf = surf; + new_sc.x = x; + new_sc.y = y; + new_sc.w = width; + new_sc.h = height; + itty = scommands.insert(itty, new_sc); + } + + // update any images loaded in the mean time + std::vector::iterator ilitty = commands.begin(); + + while (ilitty != commands.end()) + { + if ((*ilitty).instr == DrawImageLoading) + { + LoadIndex loadindex = (*ilitty).target.loadindex; + + if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end()) + { + + (*ilitty).instr = DrawImage; + (*ilitty).target.image = tvmedias_loaded[loadindex]; + incImageRef((*ilitty).target.image); + removeLoadIndexRef(loadindex); + } + } + + ilitty++; + } + + + // then clear and copy + (*itty).commands.clear(); + (*itty).commands = commands; + //increase the references + referenceSVGCommand((*itty).commands); + cleanupOrphanedRefs(); + + surfaces_mutex.unlock(); } -void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width, - std::vector& commands) +void OsdVector::removeSurface(const SurfaceVector* surf) { - surfaces_mutex.lock(); - //First determine it is already in our system - std::list::iterator itty=scommands.begin(); - while (itty!=scommands.end()) { - if ((*itty).surf==surf) { - //decrease the references - dereferenceSVGCommand((*itty).commands); - break; - } - itty++; - } - // if not insert it - if (itty==scommands.end()) { - SurfaceCommands new_sc; - new_sc.surf=surf; - new_sc.x=x; - new_sc.y=y; - new_sc.w=width; - new_sc.h=height; - itty=scommands.insert(itty,new_sc); - } - // update any images loaded in the mean time - std::vector::iterator ilitty=commands.begin(); + surfaces_mutex.lock(); + //First determine it is already in our system + std::list::iterator itty = scommands.begin(); - while (ilitty!=commands.end()) - { - if ((*ilitty).instr==DrawImageLoading) { - LoadIndex loadindex=(*ilitty).target.loadindex; - if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) { - - (*ilitty).instr=DrawImage; - (*ilitty).target.image=tvmedias_loaded[loadindex]; - incImageRef((*ilitty).target.image); - removeLoadIndexRef(loadindex); - } - } - ilitty++; - } + while (itty != scommands.end()) + { + if ((*itty).surf == surf) + { + dereferenceSVGCommand((*itty).commands); + (*itty).commands.clear(); + scommands.erase(itty); + break; + } + itty++; + } - // then clear and copy - (*itty).commands.clear(); - (*itty).commands=commands; - //increase the references - referenceSVGCommand((*itty).commands); - cleanupOrphanedRefs(); + surfaces_mutex.unlock(); - surfaces_mutex.unlock(); } -void OsdVector::removeSurface(const SurfaceVector *surf) +void OsdVector::dereferenceSVGCommand(std::vector& commands ) { - surfaces_mutex.lock(); - //First determine it is already in our system - std::list::iterator itty=scommands.begin(); - while (itty!=scommands.end()) { - if ((*itty).surf==surf) { - dereferenceSVGCommand((*itty).commands); - (*itty).commands.clear(); - scommands.erase(itty); - break; - } - itty++; - } - surfaces_mutex.unlock(); -} + std::vector::iterator sitty = commands.begin(); -void OsdVector::dereferenceSVGCommand(std::vector& commands ) -{ + while (sitty != commands.end()) + { + removeStyleRef((*sitty).getRef()); + ImageIndex ii = (*sitty).getImageIndex(); - std::vector::iterator sitty = commands.begin(); - while (sitty != commands.end()) { - removeStyleRef((*sitty).getRef()); - ImageIndex ii = (*sitty).getImageIndex(); - if (ii) removeImageRef(ii); - LoadIndex li=(*sitty).getLoadIndex(); - if (li) removeLoadIndexRef(li); - sitty++; - } + if (ii) removeImageRef(ii); + + LoadIndex li = (*sitty).getLoadIndex(); + + if (li) removeLoadIndexRef(li); + + sitty++; + } } void OsdVector::referenceSVGCommand(std::vector& commands ) { - std::vector::iterator sitty=commands.begin(); - while (sitty!=commands.end()) - { - incStyleRef((*sitty).getRef()); - ImageIndex ii=(*sitty).getImageIndex(); - if (ii) incImageRef(ii); - LoadIndex li=(*sitty).getLoadIndex(); - if (li) incLoadIndexRef(li); - sitty++; - } + std::vector::iterator sitty = commands.begin(); + + while (sitty != commands.end()) + { + incStyleRef((*sitty).getRef()); + ImageIndex ii = (*sitty).getImageIndex(); + + if (ii) incImageRef(ii); + + LoadIndex li = (*sitty).getLoadIndex(); + + if (li) incLoadIndexRef(li); + + sitty++; + } } void OsdVector::incImageRef(ImageIndex index) { - if (images_ref.find(index)==images_ref.end()) { - images_ref[index]=1; - } else { - images_ref[index]++; - } + if (images_ref.find(index) == images_ref.end()) + { + images_ref[index] = 1; + } + else + { + images_ref[index]++; + } } void OsdVector::removeImageRef(const ImageIndex ref) { - images_ref[ref]--; + images_ref[ref]--; } int OsdVector::getLoadIndexRef(LoadIndex index) { - surfaces_mutex.lock(); - if (loadindex_ref.find(index)==loadindex_ref.end()) { - return -1; - } else { - return loadindex_ref[index]; - } - surfaces_mutex.unlock(); + surfaces_mutex.lock(); + + if (loadindex_ref.find(index) == loadindex_ref.end()) + { + return -1; + } + else + { + return loadindex_ref[index]; + } + + surfaces_mutex.unlock(); } void OsdVector::incLoadIndexRef(LoadIndex index) { - if (loadindex_ref.find(index)==loadindex_ref.end()) { - loadindex_ref[index]=1; - } else { - loadindex_ref[index]++; - } + if (loadindex_ref.find(index) == loadindex_ref.end()) + { + loadindex_ref[index] = 1; + } + else + { + loadindex_ref[index]++; + } } void OsdVector::removeLoadIndexRef(const LoadIndex ref) { - loadindex_ref[ref]--; - if (loadindex_ref[ref]==0) { - //now check, if it is already loaded - std::map::iterator itty=tvmedias_loaded.find(ref); - if ( itty != tvmedias_loaded.end()) { - removeImageRef((*itty).second); // remove lock - } - tvmedias_loaded.erase(ref); -// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref); - tvmedias_load.erase(tvmedias_load_inv[ref]); - tvmedias_load_inv.erase(ref); - - reader.invalidateLoadIndex(ref); - - - } -} - - - -void OsdVector::cleanupOrphanedRefs() -{ // Do some garbage collection - - std::map::iterator mitty=monobitmaps.begin(); - while (mitty!=monobitmaps.end()) { - std::map::iterator curitty=images_ref.find((*mitty).second); - int count=(*curitty).second; - if (count==0) { - ImageIndex ref=(*curitty).first; - monobitmaps.erase(mitty++); - images_ref.erase(curitty++); - destroyImageRef(ref); - } else ++mitty; - } + loadindex_ref[ref]--; - /*map::iterator jitty=jpegs.begin(); - while (jitty!=jpegs.end()) { - map::iterator curitty=images_ref.find((*jitty).second); - int count=(*curitty).second; - if (count==0) { - ImageIndex ref=(*curitty).first; - jpegs.erase(jitty++); - images_ref.erase(curitty++); - destroyImageRef(ref); - } else ++jitty; - }*/ - - std::map::iterator titty=tvmedias.begin(); - while (titty!=tvmedias.end()) { - std::map::iterator curitty=images_ref.find((*titty).second); - int count=(*curitty).second; - if (count==0) { - ImageIndex ref=(*curitty).first; - tvmedias.erase(titty++); - images_ref.erase(curitty); - destroyImageRef(ref); - } else ++titty; - } + if (loadindex_ref[ref] == 0) + { + //now check, if it is already loaded + std::map::iterator itty = tvmedias_loaded.find(ref); + if ( itty != tvmedias_loaded.end()) + { + removeImageRef((*itty).second); // remove lock + } - std::map::iterator litty=tvmedias_load.begin(); - while (litty!=tvmedias_load.end()) { - std::map::iterator curitty=loadindex_ref.find((*litty).second); - int count=(*curitty).second; - if (count==0) { - tvmedias_load_inv.erase((*litty).second); - tvmedias_loaded.erase((*litty).second); - tvmedias_load.erase(litty++); - } else ++litty; - } + tvmedias_loaded.erase(ref); + // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref); + tvmedias_load.erase(tvmedias_load_inv[ref]); + tvmedias_load_inv.erase(ref); - std::list::iterator pitty=palettepics.begin(); - while (pitty!=palettepics.end()) { - std::map::iterator curitty=images_ref.find((*pitty)); - int count=(*curitty).second; - if (count==0) { - ImageIndex ref=(*curitty).first; - palettepics.erase(pitty++); - images_ref.erase(curitty++); - destroyImageRef(ref); - } else ++pitty; - } + reader.invalidateLoadIndex(ref); - std::map::iterator citty=images_ref.begin(); - while (citty!=images_ref.end()) { - int count=(*citty).second; - if (count==0) { - ImageIndex ref=(*citty).first; - images_ref.erase(citty++); - destroyImageRef(ref); - } else ++citty; - } + } +} - std::map::iterator sitty = styles.begin(); - while (sitty!=styles.end()) { - std::map::iterator curitty = styles_ref.find((*sitty).second); - int count=(*curitty).second; - if (count==0) { - VectorHandle ref = (*curitty).first; - styles.erase(sitty++); - styles_ref.erase(curitty++); - styles_lastit_valid=styles_ref_lastit_valid=false; - destroyStyleRef(ref); - } else ++sitty; - } +void OsdVector::cleanupOrphanedRefs() +{ + // Do some garbage collection + + std::map::iterator mitty = monobitmaps.begin(); + + while (mitty != monobitmaps.end()) + { + std::map::iterator curitty = images_ref.find((*mitty).second); + int count = (*curitty).second; + + if (count == 0) + { + ImageIndex ref = (*curitty).first; + monobitmaps.erase(mitty++); + images_ref.erase(curitty++); + destroyImageRef(ref); + } + else ++mitty; + } + + /*map::iterator jitty=jpegs.begin(); + while (jitty!=jpegs.end()) { + map::iterator curitty=images_ref.find((*jitty).second); + int count=(*curitty).second; + if (count==0) { + ImageIndex ref=(*curitty).first; + jpegs.erase(jitty++); + images_ref.erase(curitty++); + destroyImageRef(ref); + } else ++jitty; + }*/ + + std::map::iterator titty = tvmedias.begin(); + + while (titty != tvmedias.end()) + { + std::map::iterator curitty = images_ref.find((*titty).second); + int count = (*curitty).second; + + if (count == 0) + { + ImageIndex ref = (*curitty).first; + tvmedias.erase(titty++); + images_ref.erase(curitty); + destroyImageRef(ref); + } + else ++titty; + } + + + std::map::iterator litty = tvmedias_load.begin(); + + while (litty != tvmedias_load.end()) + { + std::map::iterator curitty = loadindex_ref.find((*litty).second); + int count = (*curitty).second; + + if (count == 0) + { + tvmedias_load_inv.erase((*litty).second); + tvmedias_loaded.erase((*litty).second); + tvmedias_load.erase(litty++); + } + else ++litty; + } + + std::list::iterator pitty = palettepics.begin(); + + while (pitty != palettepics.end()) + { + std::map::iterator curitty = images_ref.find((*pitty)); + int count = (*curitty).second; + + if (count == 0) + { + ImageIndex ref = (*curitty).first; + palettepics.erase(pitty++); + images_ref.erase(curitty++); + destroyImageRef(ref); + } + else ++pitty; + } + + std::map::iterator citty = images_ref.begin(); + + while (citty != images_ref.end()) + { + int count = (*citty).second; + + if (count == 0) + { + ImageIndex ref = (*citty).first; + images_ref.erase(citty++); + destroyImageRef(ref); + } + else ++citty; + } + + + std::map::iterator sitty = styles.begin(); + + while (sitty != styles.end()) + { + std::map::iterator curitty = styles_ref.find((*sitty).second); + int count = (*curitty).second; + + if (count == 0) + { + VectorHandle ref = (*curitty).first; + styles.erase(sitty++); + styles_ref.erase(curitty++); + styles_lastit_valid = styles_ref_lastit_valid = false; + destroyStyleRef(ref); + + } + else ++sitty; + + } } int OsdVector::getImageRef(ImageIndex index) { - surfaces_mutex.lock(); - if (images_ref.find(index)==images_ref.end()) { - return -1; - } else { - return images_ref[index]; - } - surfaces_mutex.unlock(); + surfaces_mutex.lock(); + + if (images_ref.find(index) == images_ref.end()) + { + return -1; + } + else + { + return images_ref[index]; + } + + surfaces_mutex.unlock(); } void OsdVector::incStyleRef(VectorHandle 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 = styles_ref.insert(std::pair(index, 1)).first; - } else { - (*styles_ref_lastit).second++; - } - styles_ref_lastit_valid=true; + 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_lastit).second++; + } + + styles_ref_lastit_valid = true; } void OsdVector::removeStyleRef(VectorHandle 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--; - } + 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--; + } } -VectorHandle OsdVector::getStyleRef(const DrawStyle &c) +VectorHandle OsdVector::getStyleRef(const DrawStyle& c) { - surfaces_mutex.lock(); - VectorHandle style_handle = 0; - 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_lastit = styles.insert(std::pair(c, style_handle)).first; - } else { - - style_handle=(*styles_lastit).second; - //Now check if the handle is valid - if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=style_handle) { - styles_ref_lastit_valid=false; - styles_ref_lastit=styles_ref.find(style_handle); - } - - if (styles_ref_lastit==styles_ref.end()) { - //invalid handle recreate - surfaces_mutex.unlock(); - style_handle=createStyleRef(c); - surfaces_mutex.lock(); - (*styles_lastit).second=style_handle; - } else styles_ref_lastit_valid=true; - } - styles_lastit_valid=true; - incStyleRef(style_handle); - surfaces_mutex.unlock(); - return style_handle; + surfaces_mutex.lock(); + VectorHandle style_handle = 0; + + 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_lastit = styles.insert(std::pair(c, style_handle)).first; + } + else + { + + style_handle = (*styles_lastit).second; + + //Now check if the handle is valid + if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != style_handle) + { + styles_ref_lastit_valid = false; + styles_ref_lastit = styles_ref.find(style_handle); + } + + if (styles_ref_lastit == styles_ref.end()) + { + //invalid handle recreate + surfaces_mutex.unlock(); + style_handle = createStyleRef(c); + surfaces_mutex.lock(); + (*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(VectorHandle 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()) { - return -1; - } else { - styles_ref_lastit_valid=true; - return (*styles_ref_lastit).second; - } + 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 + { + styles_ref_lastit_valid = true; + return (*styles_ref_lastit).second; + } } LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image) { - ImageIndex image_handle=0; - LoadIndex loadindex=0; - surfaces_mutex.lock(); - if (tvmedias.find(tvmedia)==tvmedias.end()) - { - loadindex=loadTVMedia(tvmedia); - } else { - image_handle=tvmedias[tvmedia]; - if (images_ref.find(image_handle)==images_ref.end()) { - //invalid handle recreate - loadindex=loadTVMedia(tvmedia); - image_handle=0; - } else { - incImageRef(image_handle); - } - } - /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height); - incImageRef(image_handle);*/ - image=image_handle; - surfaces_mutex.unlock(); - return loadindex; + ImageIndex image_handle = 0; + LoadIndex loadindex = 0; + surfaces_mutex.lock(); + + if (tvmedias.find(tvmedia) == tvmedias.end()) + { + loadindex = loadTVMedia(tvmedia); + } + else + { + image_handle = tvmedias[tvmedia]; + + if (images_ref.find(image_handle) == images_ref.end()) + { + //invalid handle recreate + loadindex = loadTVMedia(tvmedia); + image_handle = 0; + } + else + { + incImageRef(image_handle); + } + } + + /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height); + incImageRef(image_handle);*/ + image = image_handle; + surfaces_mutex.unlock(); + return loadindex; } LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia) { - LoadIndex index=0; - - if (tvmedias_load.find(tvmedia)==tvmedias_load.end()) - { - switch (tvmedia.getType()) { - case 3: - index=VDR::getInstance()->loadTVMediaRecThumb(tvmedia); - break; - case 4: { - index = ((long long) tvmedia.getPrimaryID()) << 32LL; - reader.addStaticImage(tvmedia.getPrimaryID()); - } break; - case 5: - index=VDR::getInstance()->loadTVMediaEventThumb(tvmedia); - break; - case 6: - index=VDR::getInstance()->loadChannelLogo(tvmedia); - break; - default: - index=VDR::getInstance()->loadTVMedia(tvmedia); - break; - } - if (tvmedia.getType()!=4 && tvmedia.getStaticFallback()>-1) { - reader.informFallback(index,tvmedia.getStaticFallback()); - } - - tvmedias_load[tvmedia]=index; - tvmedias_load_inv[index]=tvmedia; - } else { - index=tvmedias_load[tvmedia]; - } - - incLoadIndexRef(index); - - return index; + LoadIndex index = 0; + + if (tvmedias_load.find(tvmedia) == tvmedias_load.end()) + { + switch (tvmedia.getType()) + { + case 3: + index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia); + break; + + case 4: + { + index = ((long long) tvmedia.getPrimaryID()) << 32LL; + reader.addStaticImage(tvmedia.getPrimaryID()); + } break; + + case 5: + index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia); + break; + + case 6: + index = VDR::getInstance()->loadChannelLogo(tvmedia); + break; + + default: + index = VDR::getInstance()->loadTVMedia(tvmedia); + break; + } + + if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1) + { + reader.informFallback(index, tvmedia.getStaticFallback()); + } + + tvmedias_load[tvmedia] = index; + tvmedias_load_inv[index] = tvmedia; + } + else + { + index = tvmedias_load[tvmedia]; + } + + incLoadIndexRef(index); + + return index; } void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex) { - //Beware for thread safety - ImageIndex image_index=0; - - Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x",index, imageIndex); - surfaces_mutex.lock(); - TVMediaInfo tvmedia=tvmedias_load_inv[index]; - if (imageIndex) { - std::map::iterator itty=loadindex_ref.find(index); - image_index=tvmedias[tvmedia]=imageIndex; - tvmedias_loaded[index]=image_index; - - if (itty==loadindex_ref.end() || (*itty).second == 0) { - // we do not want the picture anymore . Really... - // fill images_ref in to not irritate the garbage collector - if (images_ref.find(image_index)==images_ref.end()) { - images_ref[image_index]=0; - } - } else { - incImageRef(image_index); // hold one index until all loadings refs are gone; - } - } - surfaces_mutex.unlock(); + //Beware for thread safety + ImageIndex image_index = 0; + + Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex); + surfaces_mutex.lock(); + TVMediaInfo tvmedia = tvmedias_load_inv[index]; + + if (imageIndex) + { + std::map::iterator itty = loadindex_ref.find(index); + image_index = tvmedias[tvmedia] = imageIndex; + tvmedias_loaded[index] = image_index; + + if (itty == loadindex_ref.end() || (*itty).second == 0) + { + // we do not want the picture anymore . Really... + // fill images_ref in to not irritate the garbage collector + if (images_ref.find(image_index) == images_ref.end()) + { + images_ref[image_index] = 0; + } + } + else + { + incImageRef(image_index); // hold one index until all loadings refs are gone; + } + } + + surfaces_mutex.unlock(); } @@ -709,273 +876,336 @@ ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height) } */ -ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height) +ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height) { - ImageIndex image_handle; - surfaces_mutex.lock(); - if (monobitmaps.find(base)==monobitmaps.end()) - { - surfaces_mutex.unlock(); - image_handle=createMonoBitmap(base,width,height); - surfaces_mutex.lock(); - monobitmaps[base]=image_handle; - } else { - image_handle=monobitmaps[base]; - if (images_ref.find(image_handle)==images_ref.end()) { - //invalid handle recreate - surfaces_mutex.unlock(); - image_handle=createMonoBitmap(base,width,height); - surfaces_mutex.lock(); - monobitmaps[base]=image_handle; - } - } - incImageRef(image_handle); - surfaces_mutex.unlock(); - return image_handle; + ImageIndex image_handle; + surfaces_mutex.lock(); + + if (monobitmaps.find(base) == monobitmaps.end()) + { + surfaces_mutex.unlock(); + image_handle = createMonoBitmap(base, width, height); + surfaces_mutex.lock(); + monobitmaps[base] = image_handle; + } + else + { + image_handle = monobitmaps[base]; + + if (images_ref.find(image_handle) == images_ref.end()) + { + //invalid handle recreate + surfaces_mutex.unlock(); + image_handle = createMonoBitmap(base, width, height); + surfaces_mutex.lock(); + monobitmaps[base] = image_handle; + } + } + + incImageRef(image_handle); + surfaces_mutex.unlock(); + return image_handle; } -ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data) +ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data) { - ImageIndex image_handle; - image_handle=createImagePalette(width,height,image_data,palette_data); - surfaces_mutex.lock(); - palettepics.push_back(image_handle); - incImageRef(image_handle); - surfaces_mutex.unlock(); - return image_handle; + ImageIndex image_handle; + image_handle = createImagePalette(width, height, image_data, palette_data); + surfaces_mutex.lock(); + palettepics.push_back(image_handle); + incImageRef(image_handle); + surfaces_mutex.unlock(); + return image_handle; } OsdVector::PictureReader::~PictureReader() { - decoders_lock.lock(); - while ( decoders.size()) { - PictureDecoder* dec=decoders.front(); - decoders.pop_front(); - delete dec; - } + decoders_lock.lock(); + + while ( decoders.size()) + { + PictureDecoder* dec = decoders.front(); + decoders.pop_front(); + delete dec; + } - decoders_lock.unlock(); + decoders_lock.unlock(); } void OsdVector::PictureReader::init() { - threadStart(); + threadStart(); } void OsdVector::PictureReader::shutdown() { - threadStop(); + threadStop(); } void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder) { - decoders_lock.lock(); - decoder->init(); - decoders.push_front(decoder); - decoders_lock.unlock(); + decoders_lock.lock(); + decoder->init(); + decoders.push_front(decoder); + decoders_lock.unlock(); } void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder) { - decoders_lock.lock(); - std::list::iterator itty=decoders.begin(); - while (itty!=decoders.end()) { - if ((*itty) == decoder) - { - decoders.erase(itty); - break; - } - itty++; - } - Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder"); - decoder->shutdown(); - delete decoder; - decoders_lock.unlock(); + decoders_lock.lock(); + std::list::iterator itty = decoders.begin(); + + while (itty != decoders.end()) + { + if ((*itty) == decoder) + { + decoders.erase(itty); + break; + } + + itty++; + } + + Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder"); + decoder->shutdown(); + delete decoder; + decoders_lock.unlock(); } void OsdVector::PictureReader::threadMethod() { - OsdVector *osdvector = dynamic_cast(Osd::getInstance()); - Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader"); - while (true) { - if (!threadIsActive()) { - Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader"); - threadCheckExit(); - } - - bool todos=true; - while (todos) - { - todos=false; - PictureInfo pictinf; - decoders_lock.lock(); - std::list::iterator itty=decoders.begin(); - - while (itty!=decoders.end()) { - if ((*itty)->getDecodedPicture(pictinf)) { - todos = true; - osdvector->createPicture(pictinf); - } - - itty++; - } - if (processReceivedPictures()) - { - todos = true; - } - - decoders_lock.unlock(); - } - //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader"); - - struct timespec target_time; - getClockRealTime(&target_time); - - target_time.tv_nsec+=1000000LL*10; - if (target_time.tv_nsec>999999999) { - target_time.tv_nsec-=1000000000L; - target_time.tv_sec+=1; - } - threadLock(); - threadWaitForSignalTimed(&target_time); - threadUnlock(); - //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader"); - } + OsdVector* osdvector = dynamic_cast(Osd::getInstance()); + Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader"); + + while (true) + { + if (!threadIsActive()) + { + Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader"); + threadCheckExit(); + } + + bool todos = true; + + while (todos) + { + todos = false; + PictureInfo pictinf; + decoders_lock.lock(); + std::list::iterator itty = decoders.begin(); + + while (itty != decoders.end()) + { + if ((*itty)->getDecodedPicture(pictinf)) + { + todos = true; + osdvector->createPicture(pictinf); + } + + itty++; + } + + if (processReceivedPictures()) + { + todos = true; + } + + decoders_lock.unlock(); + } + + //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader"); + + struct timespec target_time; + getClockRealTime(&target_time); + + target_time.tv_nsec += 1000000LL * 10; + + if (target_time.tv_nsec > 999999999) + { + target_time.tv_nsec -= 1000000000L; + target_time.tv_sec += 1; + } + + threadLock(); + threadWaitForSignalTimed(&target_time); + threadUnlock(); + //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader"); + } } void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index) { - pict_lock_incoming.lock(); - invalid_loadindex.insert(index); - pict_lock_incoming.unlock(); + pict_lock_incoming.lock(); + invalid_loadindex.insert(index); + pict_lock_incoming.unlock(); } void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback) { - pict_lock_incoming.lock(); - inform_fallback[index]=fallback; - pict_lock_incoming.unlock(); + pict_lock_incoming.lock(); + inform_fallback[index] = fallback; + pict_lock_incoming.unlock(); } -void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp) +void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp) { - pict_lock_incoming.lock(); - pict_incoming.push(vresp); - pict_lock_incoming.unlock(); - threadSignal(); + pict_lock_incoming.lock(); + pict_incoming.push(vresp); + pict_lock_incoming.unlock(); + threadSignal(); } void OsdVector::PictureReader::addStaticImage(unsigned int id) { - pict_lock_incoming.lock(); - pict_incoming_static.push(id); - invalid_loadindex.erase(((long long) id) << 32LL); - pict_lock_incoming.unlock(); - threadSignal(); + pict_lock_incoming.lock(); + pict_incoming_static.push(id); + invalid_loadindex.erase(((long long) id) << 32LL); + pict_lock_incoming.unlock(); + threadSignal(); } #if WIN32 -// FIXME win pragma -#pragma warning(disable : 4703) + // FIXME win pragma + #pragma warning(disable : 4703) #endif bool OsdVector::PictureReader::processReceivedPictures() { - bool decoded = false; - bool valid = true; - pict_lock_incoming.lock(); - if (pict_incoming.size()) { - VDR_ResponsePacket *vresp=pict_incoming.front(); - pict_incoming.pop(); - std::set::iterator setpos = invalid_loadindex.find(vresp->getStreamID()); - if (setpos != invalid_loadindex.end()) { - valid = false; - invalid_loadindex.erase(setpos); - } - pict_lock_incoming.unlock(); - if (!valid) { // we do not want it anymore skip it; - delete vresp; - return true; - } -// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d", -// vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag()); - bool decode = false; - bool freed = false; - UCHAR *userdata; - ULONG length; - - if (vresp->getFlag() != 2) { - userdata=vresp->getUserData(); - length=vresp->getUserDataLength(); - decode = true; - freed = true; - } else { - int fallback=-1; - pict_lock_incoming.lock(); - if (inform_fallback.find(vresp->getStreamID())!=inform_fallback.end()) { - fallback=inform_fallback[vresp->getStreamID()]; - } - pict_lock_incoming.unlock(); - if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length)) - { - decode = true; - freed = false; - } - - } - if (decode) { - std::list::iterator itty=decoders.begin(); - while (itty!=decoders.end()) { - userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed); - if (!userdata){ - decoded=true; - break; - } - itty++; - } - if (!decoded && userdata && freed){ - free(userdata); - } - } - pict_lock_incoming.lock(); - inform_fallback.erase(vresp->getStreamID()); - pict_lock_incoming.unlock(); - //else osd->informPicture(vresp->getStreamID(), 0); - delete vresp; - } else if (pict_incoming_static.size()){ - unsigned int static_id = pict_incoming_static.front(); - pict_incoming_static.pop(); - std::set::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL); - if (setpos != invalid_loadindex.end()) { - valid = false; - invalid_loadindex.erase(setpos); - } - pict_lock_incoming.unlock(); - if (!valid) { // we do not want it anymore skip it; - return true; - } - - UCHAR *userdata; - ULONG length; - if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length)) - { - std::list::iterator itty=decoders.begin(); - while (itty!=decoders.end()) { - if (!(*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){ - decoded=true; - break; - } - itty++; - } - } - } else { - pict_lock_incoming.unlock(); - } - - - if (pict_incoming.size() || pict_incoming_static.size()) return true; - return decoded; + bool decoded = false; + bool valid = true; + pict_lock_incoming.lock(); + + if (pict_incoming.size()) + { + VDR_ResponsePacket* vresp = pict_incoming.front(); + pict_incoming.pop(); + std::set::iterator setpos = invalid_loadindex.find(vresp->getStreamID()); + + if (setpos != invalid_loadindex.end()) + { + valid = false; + invalid_loadindex.erase(setpos); + } + + pict_lock_incoming.unlock(); + + if (!valid) // we do not want it anymore skip it; + { + delete vresp; + return true; + } + + // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d", + // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag()); + bool decode = false; + bool freed = false; + UCHAR* userdata; + ULONG length; + + if (vresp->getFlag() != 2) + { + userdata = vresp->getUserData(); + length = vresp->getUserDataLength(); + decode = true; + freed = true; + } + else + { + int fallback = -1; + pict_lock_incoming.lock(); + + if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end()) + { + fallback = inform_fallback[vresp->getStreamID()]; + } + + pict_lock_incoming.unlock(); + + if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length)) + { + decode = true; + freed = false; + } + + } + + if (decode) + { + std::list::iterator itty = decoders.begin(); + + while (itty != decoders.end()) + { + userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed); + + if (!userdata) + { + decoded = true; + break; + } + + itty++; + } + + if (!decoded && userdata && freed) + { + free(userdata); + } + } + + pict_lock_incoming.lock(); + inform_fallback.erase(vresp->getStreamID()); + pict_lock_incoming.unlock(); + //else osd->informPicture(vresp->getStreamID(), 0); + delete vresp; + } + else if (pict_incoming_static.size()) + { + unsigned int static_id = pict_incoming_static.front(); + pict_incoming_static.pop(); + std::set::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL); + + if (setpos != invalid_loadindex.end()) + { + valid = false; + invalid_loadindex.erase(setpos); + } + + pict_lock_incoming.unlock(); + + if (!valid) // we do not want it anymore skip it; + { + return true; + } + + UCHAR* userdata; + ULONG length; + + if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length)) + { + std::list::iterator itty = decoders.begin(); + + while (itty != decoders.end()) + { + if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false)) + { + decoded = true; + break; + } + + itty++; + } + } + } + else + { + pict_lock_incoming.unlock(); + } + + + if (pict_incoming.size() || pict_incoming_static.size()) return true; + + return decoded; } diff --git a/osdvector.h b/osdvector.h index 1cbaae7..7d4585b 100644 --- a/osdvector.h +++ b/osdvector.h @@ -37,30 +37,33 @@ #include "teletextdecodervbiebu.h" -enum SVGCommandInstr { - DrawNoop, - DrawPath, - DrawGlyph, - DrawImage, - DrawTTchar, - DrawClipping, - DrawImageLoading +enum SVGCommandInstr +{ + DrawNoop, + DrawPath, + DrawGlyph, + DrawImage, + DrawTTchar, + DrawClipping, + DrawImageLoading }; -enum PathIndex { - PIHorzLine, - PIVertLine, - PIRectangle, - PIPoint +enum PathIndex +{ + PIHorzLine, + PIVertLine, + PIRectangle, + PIPoint }; -enum Corner{ - TopLeft, - TopRight, - BottomLeft, - BottomRight, - TopMiddle, - BottomMiddle, - TopLeftLimited +enum Corner +{ + TopLeft, + TopRight, + BottomLeft, + BottomRight, + TopMiddle, + BottomMiddle, + TopLeftLimited }; typedef VectorHandle ImageIndex; @@ -68,129 +71,132 @@ typedef unsigned long long LoadIndex; class SVGCommand { -public: - SVGCommand() + public: + SVGCommand() + { + instr = DrawNoop; + x = y = w = h = 0; + reference = VECTOR_HANDLE_INIT; + }; + + inline static SVGCommand PaintPath(float ix, float iy, float iw, float ih, PathIndex path, VectorHandle ref) + { + SVGCommand nc; + nc.instr = DrawPath; + nc.x = ix; + nc.y = iy; + nc.w = iw; + nc.h = ih; + nc.target.path_index = path; + nc.reference = ref; + return nc; + }; + + inline static SVGCommand PaintImageLoading(LoadIndex load_in, float ix, float iy, float iw, float ih, VectorHandle ref, Corner corner = TopLeft) { - instr=DrawNoop; - x=y=w=h=0; - reference = VECTOR_HANDLE_INIT; + SVGCommand nc; + nc.instr = DrawImageLoading; + nc.x = ix; + nc.y = iy; + nc.w = iw; + nc.h = ih; + nc.target.loadindex = load_in; + nc.reference = ref; + nc.corner = corner; + return nc; }; - inline static SVGCommand PaintPath(float ix, float iy, float iw, float ih, PathIndex path, VectorHandle ref) - { - SVGCommand nc; - nc.instr=DrawPath; - nc.x=ix; - nc.y=iy; - nc.w=iw; - nc.h=ih; - nc.target.path_index=path; - nc.reference=ref; - return nc; - }; - - inline static SVGCommand PaintImageLoading(LoadIndex load_in, float ix, float iy, float iw, float ih, VectorHandle ref, Corner corner = TopLeft) - { - SVGCommand nc; - nc.instr=DrawImageLoading; - nc.x=ix; - nc.y=iy; - nc.w=iw; - nc.h=ih; - nc.target.loadindex=load_in; - nc.reference=ref; - nc.corner=corner; - return nc; - }; - - inline static SVGCommand PaintImage(float ix, float iy, float iw, float ih, ImageIndex image_in, VectorHandle ref, Corner corner = TopLeft) - { - SVGCommand nc; - nc.instr=DrawImage; - nc.x=ix; - nc.y=iy; - nc.w=iw; - nc.h=ih; - nc.target.image=image_in; - nc.reference=ref; - nc.corner=corner; - return nc; - }; - - - - inline static SVGCommand PaintTTchar(float ix, float iy,float iw,float ih,unsigned int ttchar_in) - { - SVGCommand nc; - nc.instr=DrawTTchar; - nc.x=ix; - nc.y=iy; - nc.w=iw; - nc.h=ih; - nc.reference=0; - nc.target.ttchar=ttchar_in; - nc.corner=TopLeft; - return nc; - }; - inline static SVGCommand PaintClipping(float ix, float iy,float iw,float ih) - { - SVGCommand nc; - nc.instr=DrawClipping; - nc.x=ix; - nc.y=iy; - nc.w=iw; - nc.h=ih; - nc.reference=0; - nc.target.ttchar=0; - return nc; - }; - - - inline static void PaintGlyph(SVGCommand& nc, float ix, float iy, wchar_t char_in, VectorHandle ref) - { - nc.instr=DrawGlyph; - nc.x=ix; - nc.y=iy; - nc.w=0; - nc.h=0; - nc.reference=ref; - nc.target.textchar=char_in; - }; - - bool Test(float tx,float ty,float tw, float th) - { - return (x>=tx) && (y>=ty) && ((x+w)<=(tx+tw)) && ((y+h)<=(ty+th)); - } - bool TTTest(float tox,float toy,float tx, float ty) - { - return (x==tox) && (toy==y) && (w==tx) && (h==ty); - } - bool Outside(float tx,float ty,float tw, float th) - { - return ((x+w)= tx) && (y >= ty) && ((x + w) <= (tx + tw)) && ((y + h) <= (ty + th)); + } + bool TTTest(float tox, float toy, float tx, float ty) + { + return (x == tox) && (toy == y) && (w == tx) && (h == ty); + } + bool Outside(float tx, float ty, float tw, float th) + { + return ((x + w) < tx) || ((y + h) < ty) || ((tx + tw) < x) || ((ty + th) < y); + } + + VectorHandle getRef() { return reference; }; + ImageIndex getImageIndex() + { + if (instr != DrawImage) return 0; + else return target.image; + }; + LoadIndex getLoadIndex() + { + if (instr != DrawImageLoading) return 0; + else return target.loadindex; + }; + + SVGCommandInstr instr; + Corner corner; + float x, y, w, h; + VectorHandle reference; + union + { + PathIndex path_index; //path_index + wchar_t textchar; + ImageIndex image; + unsigned int ttchar; + LoadIndex loadindex; + } target; }; @@ -198,10 +204,11 @@ public: class SurfaceVector; class VDR_ResponsePacket; -struct SurfaceCommands{ - const SurfaceVector* surf; - std::vector commands; - float x,y,w,h; +struct SurfaceCommands +{ + const SurfaceVector* surf; + std::vector commands; + float x, y, w, h; }; @@ -217,38 +224,38 @@ class OsdVector : public Osd int getFD(); void screenShot(const char* fileName); - virtual bool screenShot(void *buffer, int width, int height, bool osd /*include osd*/)=0; + virtual bool screenShot(void* buffer, int width, int height, bool osd /*include osd*/) = 0; - Surface * createNewSurface(); + Surface* createNewSurface(); - void Blank(); - virtual void updateBackgroundColor(DrawStyle /* bg */) {}; + void Blank(); + virtual void updateBackgroundColor(DrawStyle /* bg */) {}; - void updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width, - std::vector& commands); - void removeSurface(const SurfaceVector *surf); + void updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width, + 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 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); - virtual ImageIndex getMonoBitmapRef(void *base,int width,int height); - virtual ImageIndex getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data); + //virtual ImageIndex getJpegRef(const char* fileName, int *width,int *height); + virtual LoadIndex getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image); + virtual ImageIndex getMonoBitmapRef(void* base, int width, int height); + virtual ImageIndex getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data); - virtual bool getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length)=0; + virtual bool getStaticImageData(unsigned int static_id, UCHAR** userdata, ULONG* length) = 0; - void removeImageRef(const ImageIndex ref); - void removeLoadIndexRef(const LoadIndex ref); - VectorHandle getStyleRef(const DrawStyle &c); - virtual void removeStyleRef(VectorHandle ref); - virtual void getScreenSize(int &width, int &height)=0; - virtual void getRealScreenSize(int &width, int &height)=0; + void removeImageRef(const ImageIndex ref); + void removeLoadIndexRef(const LoadIndex ref); + VectorHandle getStyleRef(const DrawStyle& c); + virtual void removeStyleRef(VectorHandle ref); + virtual void getScreenSize(int& width, int& height) = 0; + virtual void getRealScreenSize(int& width, int& height) = 0; - // should be only called from control thread - void informPicture(LoadIndex index, ImageIndex i_index); + // should be only called from control thread + void informPicture(LoadIndex index, ImageIndex i_index); @@ -259,21 +266,23 @@ class OsdVector : public Osd class PictureDecoder; struct PictureInfo { - enum PictType { - RGBAMemBlock, - EGLImage, - D2DBitmap - }; - PictType type; - ULONG width; - ULONG height; - LoadIndex lindex; - union { - const void * image; - unsigned int handle; - }; - void *reference; - PictureDecoder* decoder; + enum PictType + { + RGBAMemBlock, + EGLImage, + D2DBitmap + }; + PictType type; + ULONG width; + ULONG height; + LoadIndex lindex; + union + { + const void* image; + unsigned int handle; + }; + void* reference; + PictureDecoder* decoder; }; @@ -281,135 +290,136 @@ class OsdVector : public Osd class PictureDecoder { - public: - PictureDecoder(PictureReader * treader) {reader=treader;}; - virtual ~PictureDecoder() {}; + public: + PictureDecoder(PictureReader* treader) {reader = treader;}; + virtual ~PictureDecoder() {}; - // its is always guaranted, that after getDecodedPicture a call to decodePicture follows, if the return value was true; - virtual unsigned char * decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem=true)=0; + // its is always guaranted, that after getDecodedPicture a call to decodePicture follows, if the return value was true; + virtual unsigned char* decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem = true) = 0; - virtual bool getDecodedPicture(struct PictureInfo& pict_inf)=0; - virtual void freeReference(void * ref)=0; + virtual bool getDecodedPicture(struct PictureInfo& pict_inf) = 0; + virtual void freeReference(void* ref) = 0; - virtual void init() {}; - virtual void shutdown() {}; + virtual void init() {}; + virtual void shutdown() {}; - protected: - PictureReader * reader; + protected: + PictureReader* reader; }; - class PictureReader: public Thread_TYPE { - public: + class PictureReader: public Thread_TYPE + { + public: - ~PictureReader(); + ~PictureReader(); - void init(); - void addDecoder(PictureDecoder*); - void removeDecoder(PictureDecoder*); + void init(); + void addDecoder(PictureDecoder*); + void removeDecoder(PictureDecoder*); - void shutdown(); + void shutdown(); - bool processReceivedPictures(); + bool processReceivedPictures(); - // should be called from control thread - void receivePicture(VDR_ResponsePacket *vresp); + // should be called from control thread + void receivePicture(VDR_ResponsePacket* vresp); - void addStaticImage(unsigned int id); + void addStaticImage(unsigned int id); - void invalidateLoadIndex(LoadIndex index); + void invalidateLoadIndex(LoadIndex index); - void informFallback(LoadIndex index, int fallback); + void informFallback(LoadIndex index, int fallback); - protected: + protected: - void threadMethod(); + void threadMethod(); - std::mutex pict_lock_incoming; //locks - std::mutex decoders_lock; - std::queue pict_incoming; - std::queue pict_incoming_static; - std::list decoders; - std::map inform_fallback; - std::set invalid_loadindex; + std::mutex pict_lock_incoming; //locks + std::mutex decoders_lock; + std::queue pict_incoming; + std::queue pict_incoming_static; + std::list decoders; + std::map inform_fallback; + std::set invalid_loadindex; - bool picture_update; + bool picture_update; }; - PictureReader *getPictReader() { return &reader;}; + PictureReader* getPictReader() { return &reader;}; -protected: + protected: PictureReader reader; - void incImageRef(ImageIndex index); - int getImageRef(ImageIndex index); - virtual void destroyImageRef(ImageIndex index)=0; - void incLoadIndexRef(LoadIndex index); - int getLoadIndexRef(LoadIndex index); + void incImageRef(ImageIndex index); + int getImageRef(ImageIndex index); + virtual void destroyImageRef(ImageIndex index) = 0; + void incLoadIndexRef(LoadIndex index); + int getLoadIndexRef(LoadIndex index); - //virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0; - virtual ImageIndex createMonoBitmap(void *base,int width,int height)=0; - virtual ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)=0; - virtual void createPicture(struct PictureInfo& pict_inf)=0; + //virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0; + virtual ImageIndex createMonoBitmap(void* base, int width, int height) = 0; + virtual ImageIndex createImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data) = 0; + virtual void createPicture(struct PictureInfo& pict_inf) = 0; - virtual LoadIndex loadTVMedia(TVMediaInfo& tvmedia); + virtual LoadIndex loadTVMedia(TVMediaInfo& tvmedia); - std::map images_ref; - std::map monobitmaps; - //map jpegs; - std::map tvmedias; - std::list palettepics; + std::map images_ref; + std::map monobitmaps; + //map jpegs; + std::map tvmedias; + std::list palettepics; - std::map loadindex_ref; - std::map tvmedias_load; - std::map tvmedias_load_inv; - std::map tvmedias_loaded; + std::map loadindex_ref; + std::map tvmedias_load; + std::map tvmedias_load_inv; + std::map tvmedias_loaded; - void incStyleRef(VectorHandle index); - int getStyleRef(VectorHandle index); - virtual void destroyStyleRef(VectorHandle index) = 0; + void incStyleRef(VectorHandle index); + int getStyleRef(VectorHandle index); + virtual void destroyStyleRef(VectorHandle index) = 0; - std::map styles; - std::map styles_ref; - std::map::iterator styles_lastit; - bool styles_lastit_valid; - std::map::iterator styles_ref_lastit; - bool styles_ref_lastit_valid; + std::map styles; + std::map styles_ref; + std::map::iterator styles_lastit; + bool styles_lastit_valid; + std::map::iterator styles_ref_lastit; + bool styles_ref_lastit_valid; - virtual VectorHandle createStyleRef(const DrawStyle &c) = 0; + virtual VectorHandle createStyleRef(const DrawStyle& c) = 0; - void dereferenceSVGCommand(std::vector& commands ); - void referenceSVGCommand(std::vector& commands ); - void cleanupOrphanedRefs(); + void dereferenceSVGCommand(std::vector& commands ); + void referenceSVGCommand(std::vector& commands ); + void cleanupOrphanedRefs(); - virtual void drawSetTrans(SurfaceCommands & sc)=0; - virtual void executeDrawCommand(SVGCommand & command)=0; + virtual void drawSetTrans(SurfaceCommands& sc) = 0; + virtual void executeDrawCommand(SVGCommand& command) = 0; - std::list scommands; + std::list scommands; - std::mutex surfaces_mutex; + std::mutex surfaces_mutex; - float byte_char_width[256]; + float byte_char_width[256]; - void drawSurfaces(); + void drawSurfaces(); }; #endif diff --git a/surfacevector.cc b/surfacevector.cc index a4c544c..124da80 100644 --- a/surfacevector.cc +++ b/surfacevector.cc @@ -27,181 +27,214 @@ SurfaceVector::SurfaceVector(OsdVector* vosd) { - osd=vosd; - commands.reserve(2048); + osd = vosd; + commands.reserve(2048); } SurfaceVector::~SurfaceVector() { - osd->removeSurface(this); - std::vector::iterator itty=commands.begin(); - while (itty!=commands.end()) - { - osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff - ImageIndex ii=(*itty).getImageIndex(); - if (ii) { - osd->removeImageRef(ii); - } - LoadIndex li=(*itty).getLoadIndex(); - if (li) osd->removeLoadIndexRef(li); - itty++; - } + osd->removeSurface(this); + std::vector::iterator itty = commands.begin(); + + while (itty != commands.end()) + { + osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff + ImageIndex ii = (*itty).getImageIndex(); + + if (ii) + { + osd->removeImageRef(ii); + } + + LoadIndex li = (*itty).getLoadIndex(); + + if (li) osd->removeLoadIndexRef(li); + + itty++; + } } int SurfaceVector::getFontHeight() { - return (int)osd->getFontHeight(); + return (int)osd->getFontHeight(); } float SurfaceVector::getCharWidth(wchar_t c) { - return osd->getCharWidth(c); + return osd->getCharWidth(c); } -int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){ - return drawText(text, x, y, 0, c); +int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c) +{ + return drawText(text, x, y, 0, c); } int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c) { - float shift=0.; - const char *run=text; - size_t length=strlen(text); + float shift = 0.; + const char* run = text; + size_t length = strlen(text); - - command_mutex.lock(); - - VectorHandle ref=osd->getStyleRef(c); - float *charwidtharray=osd->getCharWidthArray(); - int commands_size=commands.size(); - int chars=0; - commands.resize(commands_size+strlen(text)); + + command_mutex.lock(); + + VectorHandle ref = osd->getStyleRef(c); + float* charwidtharray = osd->getCharWidthArray(); + int commands_size = commands.size(); + int chars = 0; + commands.resize(commands_size + strlen(text)); #ifndef WIN32 - mbstate_t state; - wchar_t tempo; - size_t num_bytes = 1; - memset((void*)&state,0,sizeof(state)); - num_bytes=mbrtowc(&tempo, run, length, &state); - - while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) - { - 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); - } + mbstate_t state; + wchar_t tempo; + size_t num_bytes = 1; + memset((void*)&state, 0, sizeof(state)); + num_bytes = mbrtowc(&tempo, run, length, &state); + + while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0) + { + 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); + } #else - wchar_t* temptext = new wchar_t[length + 1]; - int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, - temptext, length + 1)-1; - for (int i = 0; i < real_length; i++) { - SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref); - chars++; - - float cur_shift = charwidtharray[temptext[i] & 0xFF]; - if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]); - shift += cur_shift; - } - delete[] temptext; + wchar_t* temptext = new wchar_t[length + 1]; + int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length + 1) - 1; + + for (int i = 0; i < real_length; i++) + { + SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref); + chars++; + + float cur_shift = charwidtharray[temptext[i] & 0xFF]; + + if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]); + + shift += cur_shift; + } + + delete[] temptext; #endif - commands.resize(commands_size+chars); - command_mutex.unlock(); - return 1; + commands.resize(commands_size + chars); + command_mutex.unlock(); + return 1; } int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c) { - float shift=0.; - const char *run=text; - size_t length=strlen(text); + float shift = 0.; + const char* run = text; + size_t length = strlen(text); #ifndef WIN32 - mbstate_t state; - wchar_t tempo[1]; - size_t num_bytes = 1; - memset((void*)&state,0,sizeof(state)); - num_bytes=mbrtowc(tempo, run, length, &state); - while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) - { - shift+=osd->getCharWidth(*tempo); - length -= num_bytes; - run += num_bytes; - num_bytes=mbrtowc(tempo, run, length, &state); - } + mbstate_t state; + wchar_t tempo[1]; + size_t num_bytes = 1; + memset((void*)&state, 0, sizeof(state)); + num_bytes = mbrtowc(tempo, run, length, &state); + + while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0) + { + shift += osd->getCharWidth(*tempo); + length -= num_bytes; + run += num_bytes; + num_bytes = mbrtowc(tempo, run, length, &state); + } + #else - wchar_t* temptext=new wchar_t[length+1]; - int real_length=MultiByteToWideChar(CP_UTF8, 0, text, -1, - temptext, length+ 1)-1; - for (int i = 0; i < real_length; i++) { - shift += osd->getCharWidth(temptext[i]); - } - delete[] temptext; + wchar_t* temptext = new wchar_t[length + 1]; + int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length + 1) - 1; + + for (int i = 0; i < real_length; i++) + { + shift += osd->getCharWidth(temptext[i]); + } + + delete[] temptext; #endif - return drawText(text, (int)(x-shift), y, c); + return drawText(text, (int)(x - shift), y, c); } int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c) { - float shift=0; - const char *run=text; - size_t length=strlen(text); + float shift = 0; + const char* run = text; + size_t length = strlen(text); #ifndef WIN32 - mbstate_t state; - wchar_t tempo[1]; - size_t num_bytes = 1; - memset((void*)&state,0,sizeof(state)); - num_bytes=mbrtowc(tempo, run, length, &state); - while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) - { - shift+=osd->getCharWidth(*tempo); - length -= num_bytes; - run += num_bytes; - num_bytes=mbrtowc(tempo, run, length, &state); - } -#else - wchar_t* temptext = new wchar_t[length + 1]; - int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, - temptext, length + 1)-1; - for (int i = 0; i < real_length; i++) { - shift += osd->getCharWidth(temptext[i]); - } - delete[] temptext; + mbstate_t state; + wchar_t tempo[1]; + size_t num_bytes = 1; + memset((void*)&state, 0, sizeof(state)); + num_bytes = mbrtowc(tempo, run, length, &state); + + while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0) + { + shift += osd->getCharWidth(*tempo); + length -= num_bytes; + run += num_bytes; + num_bytes = mbrtowc(tempo, run, length, &state); + } + +#else + wchar_t* temptext = new wchar_t[length + 1]; + int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length + 1) - 1; + + for (int i = 0; i < real_length; i++) + { + shift += osd->getCharWidth(temptext[i]); + } + + delete[] temptext; #endif - return drawText(text, (int)(x-shift/2.), y, c); + return drawText(text, (int)(x - shift / 2.), y, c); } -void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height) +void SurfaceVector::drawJpeg(const char* fileName, int x, int y, int* width, int* height) { - StaticArtwork index=sa_MAX; // This is for compatibility only - if (strcmp(fileName,"/vdr.jpg")==0) { - index=sa_vdrlogo; - *height=100; // this is faked so that the system does use the old coordinate system - *width=(int)ceil(190.f*osd->getPixelAspect()); - } else if (strcmp(fileName,"/wallpaperPAL.jpg")==0) { - index=sa_wallpaper; - *width=720; // this is faked so that the system does use the old coordinate system - *height=576; - } - if (index!=sa_MAX) { - TVMediaInfo info; - info.setStaticArtwork(index); - drawTVMedia(info,x,y,*width,*height,TopLeft); - } + StaticArtwork index = sa_MAX; // This is for compatibility only + + if (strcmp(fileName, "/vdr.jpg") == 0) + { + index = sa_vdrlogo; + *height = 100; // this is faked so that the system does use the old coordinate system + *width = (int)ceil(190.f * osd->getPixelAspect()); + } + else if (strcmp(fileName, "/wallpaperPAL.jpg") == 0) + { + index = sa_wallpaper; + *width = 720; // this is faked so that the system does use the old coordinate system + *height = 576; + } + + if (index != sa_MAX) + { + TVMediaInfo info; + info.setStaticArtwork(index); + drawTVMedia(info, x, y, *width, *height, TopLeft); + } } /* @@ -214,205 +247,243 @@ void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int * } */ -void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner) +void SurfaceVector::drawTVMedia(TVMediaInfo& tvmedia, float x, float y, float width, float height, Corner corner) { - command_mutex.lock(); - ImageIndex image=0; - LoadIndex load_index=osd->getTVMediaRef(tvmedia,image); - if (width!=0 && height!=0) { - removeCommands(x,y,width,height); - } - if (image) { - //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image); - commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner)); - } else { - - commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner)); - //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image); - } - command_mutex.unlock(); + command_mutex.lock(); + ImageIndex image = 0; + LoadIndex load_index = osd->getTVMediaRef(tvmedia, image); + + if (width != 0 && height != 0) + { + removeCommands(x, y, width, height); + } + + if (image) + { + //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image); + commands.push_back(SVGCommand::PaintImage(x, y, width, height, image, 0, corner)); + } + else + { + + commands.push_back(SVGCommand::PaintImageLoading(load_index, x, y, width, height, 0, corner)); + //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image); + } + + command_mutex.unlock(); } void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h) { - command_mutex.lock(); - commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h)); - command_mutex.unlock(); + command_mutex.lock(); + commands.push_back(SVGCommand::PaintClipping((float)x, (float)y, (float)w, (float)h)); + command_mutex.unlock(); } int SurfaceVector::create(UINT width, UINT height) { - sheight=height; - swidth=width; - return 1; + sheight = height; + swidth = width; + return 1; } void SurfaceVector::display() { - //nothing this is really mvp specific + //nothing this is really mvp specific } int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c) { - command_mutex.lock(); - removeCommands(x,y,width,height); // remove commands below the box - VectorHandle ref=osd->getStyleRef(c); - commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref)); - command_mutex.unlock(); - return 1; + command_mutex.lock(); + removeCommands(x, y, width, height); // remove commands below the box + VectorHandle ref = osd->getStyleRef(c); + commands.push_back(SVGCommand::PaintPath(x, y, width, height, PIRectangle, ref)); + command_mutex.unlock(); + return 1; } void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c) { - command_mutex.lock(); - VectorHandle ref = osd->getStyleRef(c); - commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref)); - command_mutex.unlock(); + command_mutex.lock(); + VectorHandle ref = osd->getStyleRef(c); + commands.push_back(SVGCommand::PaintPath(x1, y, x2 - x1, 1, PIHorzLine, ref)); + command_mutex.unlock(); } -void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){ - command_mutex.lock(); - VectorHandle ref = osd->getStyleRef(c); - commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref)); - command_mutex.unlock(); +void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c) +{ + command_mutex.lock(); + VectorHandle ref = osd->getStyleRef(c); + commands.push_back(SVGCommand::PaintPath(x, y1, 1, y2 - y1, PIVertLine, ref)); + command_mutex.unlock(); } -void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region) +void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm, const DisplayRegion& region) { - //this is complicated - command_mutex.lock(); -/* - unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight()); - for (UINT j = 0; j < bm.getHeight(); ++j){ - for (UINT i = 0; i < bm.getWidth(); ++i) - { - data[i+j*bm.getHeight()]=bm.getColour(i,j); - } - }*/ - ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]), - (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD - //free(data); - float tx=x+region.windowx; - float ty=y+region.windowy; - float th=bm.getHeight(); - float tw=bm.getWidth(); - - float scalex=720.f/((float) (region.framewidth+1)); - float scaley=576.f/((float) (region.frameheight+1)); - tx*=scalex; - ty*=scaley; - tw*=scalex; - th*=scaley; - SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0); - removeCommands(tx,ty,tw,th); - commands.push_back(temp); - command_mutex.unlock(); + //this is complicated + command_mutex.lock(); + /* + unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight()); + for (UINT j = 0; j < bm.getHeight(); ++j){ + for (UINT i = 0; i < bm.getWidth(); ++i) + { + data[i+j*bm.getHeight()]=bm.getColour(i,j); + } + }*/ + ImageIndex image = osd->getImagePalette(bm.getWidth(), bm.getHeight(), &(bm.rawData()[0]), + (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD + //free(data); + float tx = x + region.windowx; + float ty = y + region.windowy; + float th = bm.getHeight(); + float tw = bm.getWidth(); + + float scalex = 720.f / ((float) (region.framewidth + 1)); + float scaley = 576.f / ((float) (region.frameheight + 1)); + tx *= scalex; + ty *= scaley; + tw *= scalex; + th *= scaley; + SVGCommand temp = SVGCommand::PaintImage(tx, ty, tw, th, image, 0); + removeCommands(tx, ty, tw, th); + commands.push_back(temp); + command_mutex.unlock(); } -void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){ - if (!fastdraw) command_mutex.lock(); - VectorHandle ref = osd->getStyleRef(c); - commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref)); - if (!fastdraw) command_mutex.unlock(); +void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw) +{ + if (!fastdraw) command_mutex.lock(); + + VectorHandle ref = osd->getStyleRef(c); + commands.push_back(SVGCommand::PaintPath(x, y, 1, 1, PIPoint, ref)); + + if (!fastdraw) command_mutex.unlock(); } -void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour) +void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height, unsigned int width, DrawStyle& nextColour) { - command_mutex.lock(); - ImageIndex image=osd->getMonoBitmapRef(base,width,height); - VectorHandle ref = osd->getStyleRef(nextColour); - removeCommands(dx,dy,width,height); - commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref)); - command_mutex.unlock(); + command_mutex.lock(); + ImageIndex image = osd->getMonoBitmapRef(base, width, height); + VectorHandle ref = osd->getStyleRef(nextColour); + removeCommands(dx, dy, width, height); + commands.push_back(SVGCommand::PaintImage(dx, dy, height, width, image, ref)); + command_mutex.unlock(); } -int SurfaceVector::removeCommands(float x,float y,float width,float height) +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 - std::vector::iterator itty=commands.begin(); - std::vector::iterator remstart; - bool remove=false; - float cx, cy, cw, ch; - cx = cy = 0.f; - cw = swidth; - ch = sheight; - bool clipping_erases = false; - while (itty!=commands.end()) - { - if ((clipping_erases // test if clipping helps - || (*itty).Test(x,y,width,height) ) - && (*itty).instr != DrawClipping) { - //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr, - //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image); - osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff - ImageIndex ii=(*itty).getImageIndex(); - if (ii) osd->removeImageRef(ii); - LoadIndex li=(*itty).getLoadIndex(); - if (li) osd->removeLoadIndexRef(li); - if (!remove) { - remstart=itty; - remove=true; - } - } else { - if ((*itty).instr == DrawClipping) { - if ((*itty).w == 0.f && (*itty).h == 0.f) { - cx = cy = 0.f; - cw = swidth; - ch = sheight; - - } else { - cx = (*itty).x; - cy = (*itty).y; - cw = (*itty).w; - ch = (*itty).h; - } - clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height)); - } - if (remove) { - itty=commands.erase(remstart,itty); - remove=false; - } - } - itty++; - } - if (remove) { - itty=commands.erase(remstart,itty); - } - return 1; + // we iterate through all old commands in order to remove commands hidden by this rectangle + std::vector::iterator itty = commands.begin(); + std::vector::iterator remstart; + bool remove = false; + float cx, cy, cw, ch; + cx = cy = 0.f; + cw = swidth; + ch = sheight; + bool clipping_erases = false; + + while (itty != commands.end()) + { + if ((clipping_erases // test if clipping helps + || (*itty).Test(x, y, width, height) ) + && (*itty).instr != DrawClipping) + { + //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr, + //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image); + osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff + ImageIndex ii = (*itty).getImageIndex(); + + if (ii) osd->removeImageRef(ii); + + LoadIndex li = (*itty).getLoadIndex(); + + if (li) osd->removeLoadIndexRef(li); + + if (!remove) + { + remstart = itty; + remove = true; + } + } + else + { + if ((*itty).instr == DrawClipping) + { + if ((*itty).w == 0.f && (*itty).h == 0.f) + { + cx = cy = 0.f; + cw = swidth; + ch = sheight; + + } + else + { + cx = (*itty).x; + cy = (*itty).y; + cw = (*itty).w; + ch = (*itty).h; + } + + clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height)); + } + + if (remove) + { + itty = commands.erase(remstart, itty); + remove = false; + } + } + + itty++; + } + + if (remove) + { + itty = commands.erase(remstart, itty); + } + + return 1; } int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) { - // ok this method really works in a pixel oriented way - command_mutex.lock(); - osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands); - command_mutex.unlock(); - return 1; + // ok this method really works in a pixel oriented way + command_mutex.lock(); + osd->updateOrAddSurface(this, dx - sx, dy - sy, swidth, sheight, commands); + command_mutex.unlock(); + return 1; } /* This is for systems which need a locking of the drawing surface to speed up drawing */ -void SurfaceVector::startFastDraw() { - command_mutex.lock(); +void SurfaceVector::startFastDraw() +{ + command_mutex.lock(); } -void SurfaceVector::endFastDraw() { - command_mutex.unlock(); +void SurfaceVector::endFastDraw() +{ + command_mutex.unlock(); } -void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c) +void SurfaceVector::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c) { - command_mutex.lock(); - std::vector::iterator itty=commands.begin(); - while (itty!=commands.end()) - { - if ((*itty).TTTest(ox,oy,x,y) ) { - itty=commands.erase(itty); - break; - } else { - itty++; - } - } - commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal())); - command_mutex.unlock(); + command_mutex.lock(); + std::vector::iterator itty = commands.begin(); + + while (itty != commands.end()) + { + if ((*itty).TTTest(ox, oy, x, y) ) + { + itty = commands.erase(itty); + break; + } + else + { + itty++; + } + } + + commands.push_back(SVGCommand::PaintTTchar(ox, oy, x, y, c.getInternal())); + command_mutex.unlock(); } diff --git a/surfacevector.h b/surfacevector.h index a6b29c6..5c23ebb 100644 --- a/surfacevector.h +++ b/surfacevector.h @@ -43,7 +43,7 @@ class SurfaceVector : public Surface void drawJpeg(const char* fileName, int x, int y, int* width, int* height); // set width and height to zero, if the original size is wanted, if one index is non zero, // the images is scaled with correct aspect ratio, if both are non zero both are scaled - void drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner = TopLeft); + void drawTVMedia(TVMediaInfo& tvmedia, float x, float y, float width, float height, Corner corner = TopLeft); // set w and h to 0, for unsetting clipping, use correct x and y parameter so that cleanup of commands works void drawClippingRectangle(float x, float y, float w, float h); @@ -62,7 +62,7 @@ class SurfaceVector : public Surface void startFastDraw(); void endFastDraw(); - void drawTTChar(int ox, int oy,int x, int y, cTeletextChar c); + void drawTTChar(int ox, int oy, int x, int y, cTeletextChar c); void readPixel(int /* x */, int /* y */, unsigned char* /* r */, unsigned char* /* g */, unsigned char* /* b */) {}; void screenShot(const char* /* fileName */) {}; @@ -76,8 +76,8 @@ class SurfaceVector : public Surface std::mutex command_mutex; OsdVector* osd; - void drawPixel(int /* x */, int /* y */, unsigned int /* c */, bool /* fastdraw */){}; // these are not supported! - void drawPixel(int /* x */, int /* y */, Colour& /* c */, bool /* fastdraw */){}; + void drawPixel(int /* x */, int /* y */, unsigned int /* c */, bool /* fastdraw */) {}; // these are not supported! + void drawPixel(int /* x */, int /* y */, Colour& /* c */, bool /* fastdraw */) {}; }; #endif -- 2.39.5