2 Copyright 2004-2005 Chris Tallon, 2006,2011-2012 Marten Richter
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
22 #include "osdopengl.h"
\r
24 #include "videovpeogl.h"
\r
25 #include "surfaceopengl.h"
\r
28 #include "message.h"
\r
29 #include "command.h"
\r
31 #include "shaders/generic__vertex_shader.h"
\r
32 #include "shaders/osd__frag_shader.h"
\r
33 #include "shaders/frame__frag_shader.h"
\r
35 #define BACKBUFFER_WIDTH 1920
\r
36 #define BACKBUFFER_HEIGHT 1080
\r
44 OsdOpenGL::OsdOpenGL()
\r
48 external_driving=false;
\r
50 lastrendertime=getTimeMS();
\r
58 #ifdef BENCHMARK_FPS
\r
59 last_benchmark_time=getTimeMS();
\r
60 num_benchmark_frames=0;
\r
66 OsdOpenGL::~OsdOpenGL()
\r
79 int OsdOpenGL::getFD()
\r
81 if (!initted) return 0;
\r
85 Surface * OsdOpenGL::createNewSurface() {
\r
86 return (Surface*)new SurfaceOpenGL();
\r
89 int OsdOpenGL::init(void* device)
\r
91 if (initted) return 0;
\r
92 Video* video = Video::getInstance();
\r
93 //window=*((HWND*)device);
\r
95 // May be this device specific part should go to a device specific child class
\r
97 //init broadcom chipset (Move to video?)
\r
100 //First get connection to egl
\r
101 egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY);
\r
103 if (egl_display==EGL_NO_DISPLAY) {
\r
104 Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x",eglGetError());
\r
110 if (eglInitialize(egl_display, NULL, NULL)==EGL_FALSE) {
\r
111 Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x",eglGetError());
\r
115 const char *query_str=eglQueryString(egl_display,EGL_CLIENT_APIS);
\r
116 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
117 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError());
\r
118 query_str=eglQueryString(egl_display,EGL_EXTENSIONS);
\r
119 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
120 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError());
\r
122 const EGLint attributs[]={
\r
123 EGL_RED_SIZE,8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8,
\r
124 EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
\r
125 EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
\r
127 }; // Here, we might have to select the resolution!
\r
132 if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number)==EGL_FALSE) {
\r
133 Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %d",eglGetError());
\r
137 const EGLint attr_context[]={
\r
138 EGL_CONTEXT_CLIENT_VERSION,2,
\r
142 egl_context=eglCreateContext(egl_display,egl_ourconfig,EGL_NO_CONTEXT,attr_context);
\r
143 if (egl_context==EGL_NO_CONTEXT) {
\r
144 Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %d",eglGetError());
\r
148 // warning broadcom specific, get display size!
\r
149 display_width=display_height=0;
\r
150 if (graphics_get_display_size(0, &display_width, &display_height)<0) {
\r
151 Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) ");
\r
154 Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ",display_width, display_height);
\r
155 VC_RECT_T dst_rect ={0,0,display_width,display_height};
\r
156 VC_RECT_T src_rect={0,0,display_width<<16,display_height<<16};
\r
157 DISPMANX_DISPLAY_HANDLE_T bcm_display;
\r
158 DISPMANX_ELEMENT_HANDLE_T bcm_element;
\r
159 DISPMANX_UPDATE_HANDLE_T bcm_update;
\r
162 bcm_display=vc_dispmanx_display_open(0);
\r
163 bcm_update=vc_dispmanx_update_start(0);
\r
164 bcm_element=vc_dispmanx_element_add(bcm_update,bcm_display,
\r
166 &src_rect,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0);
\r
168 vc_dispmanx_update_submit_sync(bcm_update);
\r
169 static EGL_DISPMANX_WINDOW_T nativewindow;
\r
170 nativewindow.element=bcm_element;
\r
171 nativewindow.height=display_height;
\r
172 nativewindow.width=display_width;
\r
174 egl_surface = eglCreateWindowSurface(egl_display,egl_ourconfig, &nativewindow,NULL );
\r
175 if (egl_surface==EGL_NO_SURFACE) {
\r
176 Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!");
\r
180 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
\r
181 Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed");
\r
186 query_str=(const char*)glGetString(GL_VERSION) ;
\r
187 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
188 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",glGetError());
\r
190 query_str=(const char*)glGetString(GL_VENDOR) ;
\r
191 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
192 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",glGetError());
\r
194 query_str=(const char*)glGetString(GL_RENDERER) ;
\r
195 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
196 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",glGetError());
\r
198 query_str=(const char*)glGetString(GL_EXTENSIONS) ;
\r
199 if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
\r
200 else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",glGetError());
\r
205 //Now we will create the Screen
\r
206 screen = (Surface*) new SurfaceOpenGL(Surface::SCREEN);
\r
208 screen->create(video->getScreenWidth(), video->getScreenHeight());
\r
210 initted = 1; // must set this here or create surface won't work
\r
212 //glGenBuffers(1, &vB);
\r
213 //glGenBuffers(1, &iB);
\r
215 //Preparing the Shaders
\r
217 gen_shader=CreateShader(generic_vertex_shader, GL_VERTEX_SHADER);
\r
218 osd_shader=CreateShader(osd_frag_shader, GL_FRAGMENT_SHADER);
\r
220 // Create the program for osd rendering
\r
221 osd_program=glCreateProgram();
\r
222 if (osd_program==0) {
\r
223 Log::getInstance()->log("OSD", Log::WARN, "Creating glsl program failed!%d",glGetError());
\r
226 glAttachShader(osd_program,gen_shader);
\r
227 glAttachShader(osd_program,osd_shader);
\r
228 glBindAttribLocation(osd_program,0,"vec_pos");
\r
229 glBindAttribLocation(osd_program,1,"tex_coord");
\r
233 glLinkProgram(osd_program);
\r
238 glGetProgramiv(osd_program,GL_LINK_STATUS, &link_status);
\r
240 if (!link_status) {
\r
242 glGetProgramInfoLog(osd_program,1024,NULL,buffer);
\r
243 Log::getInstance()->log("OSD", Log::WARN, "Compiling Programm failed!");
\r
244 Log::getInstance()->log("OSD", Log::WARN, "%s",buffer);
\r
245 glDeleteProgram(osd_program);
\r
249 osd_sampler_loc=glGetUniformLocation(osd_program,"texture");
\r
250 // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",osd_sampler_loc,glGetError());
\r
252 // create the program for yuv frame rendering
\r
253 frame_shader=CreateShader(frame_frag_shader, GL_FRAGMENT_SHADER);
\r
255 frame_program=glCreateProgram();
\r
256 if (frame_program==0) {
\r
257 Log::getInstance()->log("OSD", Log::WARN, "Creating glsl program failed!%d",glGetError());
\r
260 glAttachShader(frame_program,gen_shader);
\r
261 glAttachShader(frame_program,frame_shader);
\r
262 glBindAttribLocation(frame_program,0,"vec_pos");
\r
263 glBindAttribLocation(frame_program,1,"tex_coord");
\r
267 glLinkProgram(frame_program);
\r
268 //GLint link_status;
\r
269 glGetProgramiv(frame_program,GL_LINK_STATUS, &link_status);
\r
271 if (!link_status) {
\r
273 glGetProgramInfoLog(frame_program,1024,NULL,buffer);
\r
274 Log::getInstance()->log("OSD", Log::WARN, "Compiling Programm failed!");
\r
275 Log::getInstance()->log("OSD", Log::WARN, "%s",buffer);
\r
276 glDeleteProgram(frame_program);
\r
280 frame_sampler_locY=glGetUniformLocation(frame_program,"textureY");
\r
281 // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());
\r
282 frame_sampler_locU=glGetUniformLocation(frame_program,"textureU");
\r
283 //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError());
\r
284 frame_sampler_locV=glGetUniformLocation(frame_program,"textureV");
\r
288 glClearColor(0.0f,0.0f,0.0f,1.f);
\r
290 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
292 if (((VideoVPEOGL*)Video::getInstance())->initUsingOSDObjects()!=1) { //call Video for init opengl stuff
\r
304 GLuint OsdOpenGL::CreateShader(const GLchar * source, GLenum type)
\r
308 ret_shad=glCreateShader(type);
\r
309 if (ret_shad==0 ) {
\r
310 Log::getInstance()->log("OSD", Log::WARN, "Creating Shader failed! %d",glGetError());
\r
313 glShaderSource(ret_shad,1,&source,NULL);
\r
314 glCompileShader(ret_shad);
\r
316 glGetShaderiv(ret_shad,GL_COMPILE_STATUS, &comp_status);
\r
318 if (!comp_status) {
\r
320 Log::getInstance()->log("OSD", Log::WARN, "Compiling Shader failed!");
\r
321 glGetShaderInfoLog(ret_shad,1024,NULL,buffer);
\r
322 Log::getInstance()->log("OSD", Log::WARN, "%s",buffer);
\r
323 glDeleteShader(ret_shad);
\r
330 void OsdOpenGL::InitVertexBuffer(float scalex,float scaley)
\r
332 Video* video=Video::getInstance();
\r
335 OSDCOLOR osdcolor={1.f,1.f,1.f,1.f};
\r
337 // osdvertices[0].c=osdcolor;
\r
338 osdvertices[0].x= (scalex);
\r
339 osdvertices[0].y=-scaley;
\r
340 osdvertices[0].z=0.5;
\r
341 osdvertices[0].u=texx;
\r
342 osdvertices[0].v=texy;
\r
343 // osdvertices[1].c=osdcolor;
\r
344 osdvertices[1].x=(scalex);
\r
345 osdvertices[1].y=(scaley);
\r
346 osdvertices[1].z=0.5f;
\r
347 osdvertices[1].u=texx;
\r
348 osdvertices[1].v=0.f;
\r
349 // osdvertices[0].c=osdcolor;
\r
350 osdvertices[2].x=(-scalex);
\r
351 osdvertices[2].y=-scaley;
\r
352 osdvertices[2].z=0.5f;
\r
353 osdvertices[2].u=0.f;
\r
354 osdvertices[2].v=texy;
\r
355 // osdvertices[3].c=osdcolor;
\r
356 osdvertices[3].x=-scalex;
\r
357 osdvertices[3].y=(scaley);
\r
358 osdvertices[3].z=0.5f;
\r
359 osdvertices[3].u=0.f;
\r
360 osdvertices[3].v=0.f;
\r
372 // glBindBuffer(GL_ARRAY_BUFFER, vB);
\r
373 // glBufferData(GL_ARRAY_BUFFER, sizeof(osdvertices), osdvertices, GL_STATIC_DRAW);
\r
376 // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iB);
\r
377 //glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(osdindices), osdindices, GL_STATIC_DRAW);
\r
384 int OsdOpenGL::shutdown()
\r
386 if (!initted) return 0;
\r
389 (((VideoVPEOGL*)Video::getInstance())->shutdownUsingOSDObjects());
\r
392 if (osd_shader!=0) glDeleteShader(osd_shader);
\r
393 if (gen_shader!=0) glDeleteShader(gen_shader);
\r
394 if (osd_program!=0) glDeleteProgram(osd_program);
\r
396 glClear(GL_COLOR_BUFFER_BIT);
\r
397 eglSwapBuffers(egl_display, egl_surface);
\r
398 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
399 eglDestroySurface(egl_display,egl_surface);
\r
400 eglDestroyContext(egl_display,egl_context);
\r
401 eglTerminate(egl_display );
\r
406 void OsdOpenGL::screenShot(const char* fileName)
\r
408 screen->screenShot(fileName);
\r
411 void OsdOpenGL::threadMethod()
\r
413 // We have to claim the gl context for this thread
\r
416 //glmutex.Unlock();
\r
417 VPEOGLFrame *frame=NULL;
\r
418 struct timespec ts;
\r
421 VideoVPEOGL* video =(VideoVPEOGL*) Video::getInstance();
\r
424 ts.tv_nsec=10*1000000LL;
\r
425 unsigned int waittime=10;
\r
427 if (!frame) frame=video->getReadyOGLFrame();
\r
429 InternalRendering(frame);
\r
430 lastrendertime=getTimeMS();
\r
431 video->returnOGLFrame(frame); //please recycle it
\r
434 long long time1=getTimeMS();
\r
435 if ((time1-lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing
\r
436 InternalRendering(NULL);
\r
437 lastrendertime=getTimeMS();
\r
440 frame=video->getReadyOGLFrame();
\r
442 if (frame) ts.tv_nsec=0;
\r
444 if (ts.tv_nsec!=0) threadWaitForSignalTimed(&ts);
\r
447 //eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
451 void OsdOpenGL::threadPostStopCleanup()
\r
458 // This function is called from the WinMain function in order to get Screen updates
\r
459 void OsdOpenGL::Render()
\r
461 if (!initted) return ;
\r
462 VPEOGLFrame* frame=NULL;
\r
463 if (external_driving) {
\r
464 long long time1=getTimeMS();
\r
465 if ((time1-lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing
\r
466 InternalRendering(NULL);
\r
467 lastrendertime=getTimeMS();
\r
469 //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads
\r
472 struct timespec ts;
\r
473 clock_gettime(CLOCK_MONOTONIC, &ts);
\r
474 long long time1=ts.tv_sec*1000+ts.tv_nsec/1000000LL;
\r
475 if ((time1-lastrendertime)>100) {//10 fps for OSD updates are enough, avoids tearing
\r
476 InternalRendering(NULL);
\r
477 lastrendertime=getTimeMS();
\r
486 void OsdOpenGL::RenderDS(VPEOGLFrame* frame){
\r
487 if (!initted) return;
\r
488 if (external_driving) {
\r
489 InternalRendering(frame);
\r
490 lastrendertime=getTimeMS();
\r
495 void OsdOpenGL::InternalRendering(VPEOGLFrame* frame){
\r
497 /* HRESULT losty=d3ddevice->TestCooperativeLevel();
\r
498 if (losty==D3DERR_DEVICELOST) {
\r
501 return; //Device Lost
\r
503 if (losty==D3DERR_DEVICENOTRESET){
\r
508 WaitForSingleObject(event,INFINITE);
\r
513 LPDIRECT3DSURFACE9 targetsurf;
\r
516 targetsurf=swapsurf;
\r
517 d3ddevice->SetRenderTarget(0,swapsurf);//Stupid VMR manipulates the render target
\r
521 targetsurf=d3drtsurf;
\r
522 d3ddevice->SetRenderTarget(0,d3drtsurf);//Stupid VMR manipulates the render target
\r
524 D3DSURFACE_DESC targetdesc;
\r
525 targetsurf->GetDesc(&targetdesc);
\r
527 if (external_driving) {
\r
528 //Copy video to Backbuffer
\r
529 if (present!=NULL ) {
\r
530 VideoWin* video =(VideoWin*) Video::getInstance();
\r
531 /*calculating destination rect *
\r
532 RECT destrect={0,0,/*video->getScreenWidth()* targetdesc.Width,
\r
533 /*video->getScreenHeight()*targetdesc.Height};
\r
534 UCHAR mode=video->getMode();
\r
536 case Video::EIGHTH:
\r
537 destrect.right=destrect.right/2;
\r
538 destrect.bottom=destrect.bottom/2;
\r
539 case Video::QUARTER:
\r
540 destrect.right=destrect.right/2+video->getPosx()*2;
\r
541 destrect.bottom=destrect.bottom/2+video->getPosy()*2;
\r
542 destrect.left=video->getPosx()*2;
\r
543 destrect.top=video->getPosy()*2;
\r
544 d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
\r
547 D3DSURFACE_DESC surf_desc;
\r
548 present->GetDesc(&surf_desc);//for chop sides
\r
549 RECT sourcerect= {0,0,surf_desc.Width,surf_desc.Height};
\r
550 if (video->getPseudoTVsize()==Video::ASPECT4X3
\r
551 && video->getMode()==Video::NORMAL
\r
552 && video->getAspectRatio()==Video::ASPECT16X9) {
\r
553 unsigned int correction=((double) (surf_desc.Width))*4.*9./3./16.;
\r
554 sourcerect.left=(surf_desc.Width-correction)/2;
\r
555 sourcerect.right=sourcerect.left+correction;
\r
557 d3ddevice->StretchRect(present,&sourcerect,targetsurf ,&destrect,filter_type);
\r
561 VideoWin* video =(VideoWin*) Video::getInstance();
\r
563 if (!video->isVideoOn()) d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
\r
567 //InitVertexBuffer(display_width,display_height);
\r
568 InitVertexBuffer(1.f,1.f);
\r
571 glViewport(0, 0, display_width,display_height);
\r
573 glClear(GL_COLOR_BUFFER_BIT);
\r
580 //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError());
\r
581 glUseProgram(frame_program);
\r
582 //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError());
\r
583 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), osdvertices);
\r
584 glEnableVertexAttribArray(0);
\r
585 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u));
\r
586 glEnableVertexAttribArray(1);
\r
587 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), osdvertices);
\r
588 glEnableVertexAttribArray(0);
\r
589 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u));
\r
590 glEnableVertexAttribArray(1);
\r
593 //Log::getInstance()->log("OSD", Log::WARN, "mark2 glerror %x",glGetError());
\r
596 glActiveTexture(GL_TEXTURE2);
\r
597 glBindTexture(GL_TEXTURE_2D,frame->textures[2]);
\r
598 glUniform1i(frame_sampler_locV,2);
\r
599 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
\r
600 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
\r
603 glActiveTexture(GL_TEXTURE1);
\r
604 glBindTexture(GL_TEXTURE_2D,frame->textures[1]);
\r
605 glUniform1i(frame_sampler_locU,1);
\r
606 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
\r
607 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
\r
610 glActiveTexture(GL_TEXTURE0);
\r
611 glBindTexture(GL_TEXTURE_2D,frame->textures[0]);
\r
612 glUniform1i(frame_sampler_locY,0);
\r
613 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
\r
614 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
\r
618 //Log::getInstance()->log("OSD", Log::WARN, "mark8 glerror %x %x",glGetError(),osd_sampler_loc);
\r
622 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
\r
623 glEnable(GL_BLEND);
\r
624 glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_ONE);
\r
628 glUseProgram(osd_program);
\r
629 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), osdvertices);
\r
630 glEnableVertexAttribArray(0);
\r
631 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u));
\r
632 glEnableVertexAttribArray(1);
\r
635 glActiveTexture(GL_TEXTURE0);
\r
636 glBindTexture(GL_TEXTURE_2D,((SurfaceOpenGL*)screen)->getTexture());
\r
638 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
\r
639 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
\r
641 glUniform1i(osd_sampler_loc,0);
\r
643 if (0) { //This is ok for ffmpeg rendering not OMX
\r
644 glEnable(GL_BLEND);
\r
645 glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_ONE);
\r
648 /* glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),
\r
649 (GLvoid*)(((char*)osdvertices)+3*sizeof(GLfloat)));
\r
650 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),
\r
651 (GLvoid*)(((char*)osdvertices)+3*sizeof(GLfloat)+sizeof(OSDCOLOR)));*/
\r
652 //glDisable(GL_LIGHTING);
\r
653 //glEnable(GL_TEXTURE_2D);
\r
654 //glEnable(GL_BLEND);
\r
655 //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
656 //glDepthFunc(GL_ALWAYS);
\r
657 //glDisable(GL_DEPTH_TEST);
\r
658 //glDisable(GL_STENCIL_TEST);
\r
659 //glDisable(GL_CULL_FACE);
\r
664 glActiveTexture(GL_TEXTURE0);
\r
665 glBindTexture(GL_TEXTURE_2D,((SurfaceOpenGL*)screen)->getTexture());
\r
666 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
\r
667 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);*/
\r
668 // glUniform1i(mTextureUniformHandle, present);
\r
672 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
\r
674 //glDrawElements(GL_TRIANGLES, sizeof(osdindices)/sizeof(osdindices[0]), GL_UNSIGNED_BYTE, 0);
\r
679 /* glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), 0);
\r
680 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),
\r
681 (GLvoid*)(3*sizeof(GLfloat)));
\r
682 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),
\r
683 (GLvoid*)(3*sizeof(GLfloat)+sizeof(OSDCOLOR)));*/
\r
685 //glDisable(GL_BLEND);
\r
686 //glDisable(GL_TEXTURE_2D);
\r
688 //Show it to the user!
\r
689 eglSwapBuffers(egl_display, egl_surface);
\r
692 #ifdef BENCHMARK_FPS
\r
693 num_benchmark_frames++;
\r
694 if (getTimeMS()-last_benchmark_time>4000) {
\r
695 float fps=1000./(float)(getTimeMS()-last_benchmark_time);
\r
696 fps*=((float)num_benchmark_frames);
\r
697 num_benchmark_frames=0;
\r
698 Log::getInstance()->log("OSD", Log::NOTICE, "Current FPS %g", fps);
\r
699 last_benchmark_time=getTimeMS();
\r
706 // if (!external_driving) {
\r
707 // Sleep(4);//The User can wait for 4 milliseconds to see his changes
\r
711 bool OsdOpenGL::DoLost(){
\r
713 Log::getInstance()->log("OSD", Log::WARN, "Direct3D Device Lost! Reobtaining...");
\r
715 if (external_driving && dsallocator!=NULL) {
\r
716 dsallocator->LostDevice(d3ddevice,d3d); //Propagate the information through DS
\r
718 //First we free up all resources
\r
719 Video* video = Video::getInstance();
\r
720 ((SurfaceWin*)screen)->ReleaseSurface();
\r
721 if (d3drtsurf) d3drtsurf->Release();
\r
723 D3DPRESENT_PARAMETERS d3dparas;
\r
724 ZeroMemory(&d3dparas,sizeof(d3dparas));
\r
725 d3dparas.BackBufferWidth=BACKBUFFER_WIDTH;
\r
726 d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT;
\r
727 d3dparas.Windowed=TRUE;
\r
728 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
\r
730 if (swapsurf) {swapsurf->Release();swapsurf=NULL;};
\r
731 if (swappy) {swappy->Release();swappy=NULL;};
\r
733 if (d3ddevice->Reset(&d3dparas)!=D3D_OK){
\r
736 d3ddevice->GetRenderTarget(0,&d3drtsurf);
\r
737 if (d3ddevman) d3ddevman->ResetDevice(d3ddevice,dxvatoken);
\r
738 //InitVertexBuffer();
\r
739 //Redraw Views, Chris could you add a member function to BoxStack, so that
\r
740 // I can cause it to completely redraw the Views?
\r
741 // Otherwise the OSD would be distorted after Device Lost
\r
747 screen->create(video->getScreenWidth(), video->getScreenHeight());
\r
748 screen->display();*/
\r
755 void OsdOpenGL::BeginPainting() {//We synchronize calls to d3d between different threads
\r
758 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
\r
759 Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
\r
765 void OsdOpenGL::EndPainting() {
\r
766 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
\r
770 void OsdOpenGL::setExternalDriving(/*DsAllocator* dsall,*/unsigned int width, unsigned height) {
\r
775 d3ddevice->StretchRect(swapsurf,NULL,d3drtsurf,NULL,filter_type);
\r
776 LPDIRECT3DSWAPCHAIN9 temp=swappy;
\r
777 LPDIRECT3DSURFACE9 tempsurf=swapsurf;
\r
781 tempsurf->Release();
\r
786 external_driving=false;
\r
790 WaitForSingleObject(event,INFINITE);//We will only return if we are initted
\r
793 if (width>BACKBUFFER_WIDTH || height>BACKBUFFER_HEIGHT)
\r
795 D3DPRESENT_PARAMETERS d3dparas;
\r
796 ZeroMemory(&d3dparas,sizeof(d3dparas));
\r
797 d3dparas.BackBufferWidth=width;
\r
798 d3dparas.BackBufferHeight=height;
\r
799 d3dparas.Windowed=TRUE;
\r
800 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
\r
801 if (d3ddevice->CreateAdditionalSwapChain(&d3dparas,&swappy)!=D3D_OK){
\r
802 Log::getInstance()->log("OSD", Log::WARN, "Could not create Swap Chain!");
\r
805 swappy->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&swapsurf);
\r
807 Log::getInstance()->log("OSD", Log::INFO, "Create Additional Swap Chain %d %d!",width,height);
\r
811 external_driving=true;
\r
816 void OsdOpenGL::Blank() {
\r
818 glClearColor(0.15f, 0.25f, 0.35f, 1.0f); // change this to black after testing
\r
819 glClear( GL_COLOR_BUFFER_BIT );
\r
820 glClear( GL_DEPTH_BUFFER_BIT );
\r