]> git.vomp.tv Git - vompclient-marten.git/blob - osdopengl.cc
Added FPS benchmarking
[vompclient-marten.git] / osdopengl.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon, 2006,2011-2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \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
10 \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
15 \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
19 */\r
20 \r
21 \r
22 #include "osdopengl.h"\r
23 #include "mtd.h"\r
24 #include "videovpeogl.h"\r
25 #include "surfaceopengl.h"\r
26 \r
27 \r
28 #include "message.h"\r
29 #include "command.h"\r
30 \r
31 #include "shaders/generic__vertex_shader.h"\r
32 #include "shaders/osd__frag_shader.h"\r
33 \r
34 #define  BACKBUFFER_WIDTH 1920\r
35 #define  BACKBUFFER_HEIGHT 1080\r
36 \r
37 \r
38 \r
39 long long getTimeMS() {\r
40         struct timespec ts;\r
41         clock_gettime(CLOCK_MONOTONIC, &ts);\r
42         return ts.tv_sec*1000+ts.tv_nsec/1000000LL;\r
43 }\r
44 \r
45 \r
46 \r
47 OsdOpenGL::OsdOpenGL()\r
48 {\r
49   glmutex.Lock();\r
50 \r
51   external_driving=false;\r
52 \r
53   lastrendertime=getTimeMS();\r
54   display_height=0;\r
55   display_width=0;\r
56   osd_shader=0;\r
57   gen_shader=0;\r
58   osd_program=0;\r
59 \r
60 #ifdef BENCHMARK_FPS\r
61         last_benchmark_time=getTimeMS();\r
62         num_benchmark_frames=0;\r
63 #endif\r
64 \r
65   \r
66 }\r
67 \r
68 OsdOpenGL::~OsdOpenGL()\r
69 {\r
70 \r
71   if (initted) \r
72   {\r
73           threadStop();\r
74                 shutdown();\r
75   }\r
76 \r
77 \r
78   glmutex.Unlock();\r
79 }\r
80 \r
81 int OsdOpenGL::getFD()\r
82 {\r
83   if (!initted) return 0;\r
84   return fdOsd;\r
85 }\r
86 \r
87 Surface * OsdOpenGL::createNewSurface() {\r
88         return (Surface*)new SurfaceOpenGL();\r
89 }\r
90 \r
91 int OsdOpenGL::init(void* device)\r
92 {\r
93   if (initted) return 0;\r
94   Video* video = Video::getInstance();\r
95    //window=*((HWND*)device);\r
96   \r
97    // May be this device specific part should go to a device specific child class\r
98 \r
99    //init broadcom chipset (Move to video?)\r
100    bcm_host_init();\r
101 \r
102    //First get connection to egl\r
103    egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY);\r
104 \r
105    if (egl_display==EGL_NO_DISPLAY) {\r
106            Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display!",eglGetError());\r
107            return 0;\r
108    }\r
109 \r
110    if (eglInitialize(egl_display, NULL, NULL)==EGL_FALSE) {\r
111            Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %d",eglGetError());\r
112            return 0;\r
113    }\r
114 \r
115    const EGLint attributs[]={\r
116                  EGL_RED_SIZE,8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8,\r
117          EGL_SURFACE_TYPE, EGL_WINDOW_BIT,\r
118          EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,\r
119          EGL_NONE\r
120    }; // Here, we might have to select the resolution!\r
121 \r
122    EGLConfig ourconfig; //maybe accept more configs?\r
123    EGLint number;\r
124 \r
125    if (eglChooseConfig(egl_display, attributs, &ourconfig, 1, &number)==EGL_FALSE) {\r
126            Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %d",eglGetError());\r
127            return 0;\r
128    }\r
129 \r
130    const EGLint attr_context[]={\r
131                    EGL_CONTEXT_CLIENT_VERSION,2,\r
132           EGL_NONE\r
133       };\r
134 \r
135    egl_context=eglCreateContext(egl_display,ourconfig,EGL_NO_CONTEXT,attr_context);\r
136    if (egl_context==EGL_NO_CONTEXT) {\r
137            Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %d",eglGetError());\r
138            return 0;\r
139    }\r
140 \r
141    // warning broadcom specific, get display size!\r
142    display_width=display_height=0;\r
143    if (graphics_get_display_size(0, &display_width, &display_height)<0) {\r
144            Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) ");\r
145            return 0;\r
146    }\r
147    Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ",display_width, display_height);\r
148    VC_RECT_T dst_rect ={0,0,display_width,display_height};\r
149    VC_RECT_T src_rect={0,0,display_width<<16,display_height<<16};\r
150    DISPMANX_DISPLAY_HANDLE_T bcm_display;\r
151    DISPMANX_ELEMENT_HANDLE_T bcm_element;\r
152    DISPMANX_UPDATE_HANDLE_T  bcm_update;\r
153 \r
154 \r
155    bcm_display=vc_dispmanx_display_open(0);\r
156    bcm_update=vc_dispmanx_update_start(0);\r
157    bcm_element=vc_dispmanx_element_add(bcm_update,bcm_display,\r
158          0,&dst_rect, 0,\r
159          &src_rect,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0);\r
160 \r
161    vc_dispmanx_update_submit_sync(bcm_update);\r
162    static EGL_DISPMANX_WINDOW_T nativewindow;\r
163    nativewindow.element=bcm_element;\r
164    nativewindow.height=display_height;\r
165    nativewindow.width=display_width;\r
166 \r
167    egl_surface = eglCreateWindowSurface(egl_display,ourconfig, &nativewindow,NULL );\r
168    if (egl_surface==EGL_NO_SURFACE) {\r
169            Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!");\r
170            return 0;\r
171    }\r
172 \r
173    if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {\r
174            Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed");\r
175                    return 0;\r
176    }\r
177    // Test stuff\r
178 \r
179 \r
180 \r
181   //Now we will create the Screen\r
182   screen = (Surface*) new SurfaceOpenGL(Surface::SCREEN);\r
183 \r
184   screen->create(video->getScreenWidth(), video->getScreenHeight());\r
185   screen->display();\r
186   initted = 1; // must set this here or create surface won't work\r
187 \r
188   //glGenBuffers(1, &vB);\r
189   //glGenBuffers(1, &iB);\r
190 \r
191   //Preparing the Shaders\r
192 \r
193   gen_shader=CreateShader(generic_vertex_shader, GL_VERTEX_SHADER);\r
194   osd_shader=CreateShader(osd_frag_shader, GL_FRAGMENT_SHADER);\r
195 \r
196 \r
197   osd_program=glCreateProgram();\r
198   if (osd_program==0) {\r
199           Log::getInstance()->log("OSD", Log::WARN, "Creating glsl program failed!%d",glGetError());\r
200       return 0;\r
201   }\r
202   glAttachShader(osd_program,gen_shader);\r
203   glAttachShader(osd_program,osd_shader);\r
204   glBindAttribLocation(osd_program,0,"vec_pos");\r
205   glBindAttribLocation(osd_program,1,"tex_coord");\r
206 \r
207   osd_sampler_loc=glGetUniformLocation(osd_program,"texture");\r
208 \r
209   glLinkProgram(osd_program);\r
210   GLint link_status;\r
211   glGetShaderiv(osd_program,GL_LINK_STATUS, &link_status);\r
212 \r
213   if (!link_status) {\r
214           char buffer[1024];\r
215           glGetProgramInfoLog(osd_program,1024,NULL,buffer);\r
216           Log::getInstance()->log("OSD", Log::WARN, "Compiling Programm failed!");\r
217           Log::getInstance()->log("OSD", Log::WARN, "%s",buffer);\r
218           glDeleteProgram(osd_program);\r
219           return 0;\r
220   }\r
221 \r
222   glClearColor(0.0f,0.0f,0.0f,1.f);\r
223 \r
224   eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
225   glmutex.Unlock();\r
226   threadStart();\r
227 \r
228   return 1;\r
229 }\r
230 \r
231 \r
232 GLuint OsdOpenGL::CreateShader(const GLchar * source, GLenum type)\r
233 {\r
234         GLuint ret_shad=0;\r
235 \r
236         ret_shad=glCreateShader(type);\r
237         if (ret_shad==0 ) {\r
238                 Log::getInstance()->log("OSD", Log::WARN, "Creating Shader failed! %d",glGetError());\r
239                 return 0;\r
240         }\r
241         glShaderSource(ret_shad,1,&source,NULL);\r
242         glCompileShader(ret_shad);\r
243         GLint comp_status;\r
244         glGetShaderiv(ret_shad,GL_COMPILE_STATUS, &comp_status);\r
245 \r
246         if (!comp_status) {\r
247                 char buffer[1024];\r
248                 Log::getInstance()->log("OSD", Log::WARN, "Compiling Shader failed!");\r
249                 glGetShaderInfoLog(ret_shad,1024,NULL,buffer);\r
250                 Log::getInstance()->log("OSD", Log::WARN, "%s",buffer);\r
251                 glDeleteShader(ret_shad);\r
252                 return 0;\r
253         }\r
254         return ret_shad;\r
255 }\r
256 \r
257         \r
258 void OsdOpenGL::InitVertexBuffer(float  scalex,float scaley)\r
259 {\r
260   Video* video=Video::getInstance();\r
261   float texx=1.f;\r
262   float texy=1.f;\r
263   OSDCOLOR osdcolor={1.f,1.f,1.f,1.f};\r
264 \r
265  // osdvertices[0].c=osdcolor;\r
266   osdvertices[0].x= (scalex);\r
267   osdvertices[0].y=-scaley;\r
268   osdvertices[0].z=0.5;\r
269   osdvertices[0].u=texx;\r
270   osdvertices[0].v=texy;\r
271  // osdvertices[1].c=osdcolor;\r
272   osdvertices[1].x=(scalex);\r
273   osdvertices[1].y=(scaley);\r
274   osdvertices[1].z=0.5f;\r
275   osdvertices[1].u=texx;\r
276   osdvertices[1].v=0.f;\r
277   //  osdvertices[0].c=osdcolor;\r
278   osdvertices[2].x=(-scalex);\r
279   osdvertices[2].y=-scaley;\r
280   osdvertices[2].z=0.5f;\r
281   osdvertices[2].u=0.f;\r
282   osdvertices[2].v=texy;\r
283  // osdvertices[3].c=osdcolor;\r
284   osdvertices[3].x=-scalex;\r
285   osdvertices[3].y=(scaley);\r
286   osdvertices[3].z=0.5f;\r
287   osdvertices[3].u=0.f;\r
288   osdvertices[3].v=0.f;\r
289   \r
290   osdindices[0]=0;\r
291   osdindices[1]=1;\r
292   osdindices[2]=2;\r
293   osdindices[3]=0;\r
294   osdindices[4]=2;\r
295   osdindices[5]=3;\r
296 \r
297 \r
298 \r
299 \r
300  // glBindBuffer(GL_ARRAY_BUFFER, vB);\r
301  // glBufferData(GL_ARRAY_BUFFER, sizeof(osdvertices), osdvertices, GL_STATIC_DRAW);\r
302 \r
303 \r
304  // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iB);\r
305   //glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(osdindices), osdindices, GL_STATIC_DRAW);\r
306 \r
307 \r
308 \r
309   return;\r
310 }\r
311 \r
312 int OsdOpenGL::shutdown()\r
313 {\r
314   if (!initted) return 0;\r
315   initted = 0;\r
316 \r
317 \r
318   if (osd_shader!=0) glDeleteShader(osd_shader);\r
319   if (gen_shader!=0) glDeleteShader(gen_shader);\r
320   if (osd_program!=0) glDeleteProgram(osd_program);\r
321 \r
322   glClear(GL_COLOR_BUFFER_BIT);\r
323   eglSwapBuffers(egl_display, egl_surface);\r
324   eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
325   eglDestroySurface(egl_display,egl_surface);\r
326   eglDestroyContext(egl_display,egl_context);\r
327   eglTerminate(egl_display );\r
328 \r
329   return 1;\r
330 }\r
331 \r
332 void OsdOpenGL::screenShot(const char* fileName)\r
333 {\r
334   screen->screenShot(fileName);\r
335 }\r
336 \r
337 void OsdOpenGL::threadMethod()\r
338 {\r
339         // We have to claim the gl context for this thread\r
340         //glmutex.Lock();\r
341 \r
342         //glmutex.Unlock();\r
343         while (true)\r
344         {\r
345                 unsigned int waittime=10;\r
346                 if (initted){\r
347                 //      if (evrstate==EVR_pres_off || evrstate==EVR_pres_pause)\r
348                 //      {\r
349                                 Render();\r
350                                 //TODO get surfaces from Video object\r
351         /*              } else if (evrstate==EVR_pres_started)\r
352                         {\r
353                                 LPDIRECT3DSURFACE9 surf;\r
354                                 if (dsallocator) dsallocator->GetNextSurface(&surf,&waittime);\r
355                                 if (surf==NULL)\r
356                                 {\r
357                                         Render();\r
358                                 }\r
359                                 else\r
360                                 {\r
361                                         RenderDS(surf);\r
362                                         surf->Release();\r
363                                         if (dsallocator) dsallocator->DiscardSurfaceandgetWait(&waittime);\r
364                                 }\r
365                         }*/\r
366                 }\r
367                 threadCheckExit();\r
368                 if (waittime!=0) MILLISLEEP(min(10,waittime));\r
369                 //Sleep(1);\r
370         }\r
371         //eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
372 }\r
373 \r
374 \r
375 void OsdOpenGL::threadPostStopCleanup()\r
376 {\r
377         //Doing nothing\r
378         //goo;\r
379 }\r
380 \r
381 \r
382 // This function is called from the WinMain function in order to get Screen updates\r
383 void OsdOpenGL::Render()\r
384 {\r
385         if (!initted) return ;\r
386         if (external_driving) {\r
387         long long time1=getTimeMS();\r
388 \r
389                 if ((time1-lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing\r
390                         InternalRendering(NULL);\r
391                         lastrendertime=getTimeMS();\r
392         } else {\r
393                    //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads\r
394         }\r
395         } else {\r
396                 struct timespec ts;\r
397                 clock_gettime(CLOCK_MONOTONIC, &ts);\r
398                 long long time1=ts.tv_sec*1000+ts.tv_nsec/1000000LL;\r
399                 if ((time1-lastrendertime)>50) {//10 fps for OSD updates are enough, avoids tearing\r
400                         InternalRendering(NULL);\r
401                         lastrendertime=getTimeMS();\r
402                 } else {\r
403                         //Sleep(5);\r
404                 \r
405                 }\r
406                 \r
407         }\r
408 }\r
409 \r
410 void OsdOpenGL::RenderDS(GLuint  present){\r
411         if (!initted) return; \r
412         if (external_driving) {\r
413                 InternalRendering(present);\r
414                 lastrendertime=getTimeMS();\r
415         }\r
416 }\r
417 \r
418 \r
419 void OsdOpenGL::InternalRendering(GLuint  present){\r
420     BeginPainting();\r
421   /*  HRESULT losty=d3ddevice->TestCooperativeLevel();\r
422     if (losty==D3DERR_DEVICELOST) {\r
423         //Sleep(10);\r
424                 EndPainting();\r
425         return; //Device Lost\r
426     }\r
427     if (losty==D3DERR_DEVICENOTRESET){\r
428            EndPainting();\r
429        DoLost();\r
430        return;\r
431     }\r
432         WaitForSingleObject(event,INFINITE);\r
433         */\r
434    \r
435         \r
436 /*\r
437     LPDIRECT3DSURFACE9 targetsurf;\r
438         if (swappy)\r
439         {\r
440                 targetsurf=swapsurf;\r
441                 d3ddevice->SetRenderTarget(0,swapsurf);//Stupid VMR manipulates the render target\r
442         } \r
443         else\r
444         {\r
445                 targetsurf=d3drtsurf;\r
446                 d3ddevice->SetRenderTarget(0,d3drtsurf);//Stupid VMR manipulates the render target\r
447         }\r
448         D3DSURFACE_DESC targetdesc;\r
449         targetsurf->GetDesc(&targetdesc);\r
450 \r
451         if (external_driving) {\r
452                 //Copy video to Backbuffer\r
453                 if (present!=NULL ) {\r
454                         VideoWin* video =(VideoWin*) Video::getInstance();\r
455                         /*calculating destination rect *\r
456                         RECT destrect={0,0,/*video->getScreenWidth()* targetdesc.Width,\r
457                                 /*video->getScreenHeight()*targetdesc.Height};\r
458                         UCHAR mode=video->getMode();\r
459                         switch (mode) {\r
460                         case Video::EIGHTH:\r
461                         destrect.right=destrect.right/2;\r
462                         destrect.bottom=destrect.bottom/2;\r
463                         case Video::QUARTER:\r
464                         destrect.right=destrect.right/2+video->getPosx()*2;\r
465                         destrect.bottom=destrect.bottom/2+video->getPosy()*2;\r
466                         destrect.left=video->getPosx()*2;\r
467                         destrect.top=video->getPosy()*2;\r
468                         d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);\r
469                         break;\r
470                         };\r
471                         D3DSURFACE_DESC surf_desc;\r
472                         present->GetDesc(&surf_desc);//for chop sides\r
473                         RECT sourcerect= {0,0,surf_desc.Width,surf_desc.Height};\r
474                         if (video->getPseudoTVsize()==Video::ASPECT4X3 \r
475                                 && video->getMode()==Video::NORMAL \r
476                                 && video->getAspectRatio()==Video::ASPECT16X9) {\r
477                                         unsigned int correction=((double) (surf_desc.Width))*4.*9./3./16.;\r
478                                         sourcerect.left=(surf_desc.Width-correction)/2;\r
479                                         sourcerect.right=sourcerect.left+correction;\r
480                         }\r
481                         d3ddevice->StretchRect(present,&sourcerect,targetsurf ,&destrect,filter_type);\r
482 \r
483                 }\r
484         } else {\r
485                 VideoWin* video =(VideoWin*) Video::getInstance();\r
486                 //Clear Background\r
487                 if (!video->isVideoOn()) d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);\r
488         }*/\r
489 \r
490 \r
491         //InitVertexBuffer(display_width,display_height);\r
492     InitVertexBuffer(1.f,1.f);\r
493 \r
494 \r
495         glViewport(0, 0, display_width,display_height);\r
496 \r
497         glClear(GL_COLOR_BUFFER_BIT);\r
498         glUseProgram(osd_program);\r
499 \r
500         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), osdvertices);\r
501         glEnableVertexAttribArray(0);\r
502         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u));\r
503         glEnableVertexAttribArray(1);\r
504 \r
505 \r
506 \r
507 \r
508         glActiveTexture(GL_TEXTURE0);\r
509         glBindTexture(GL_TEXTURE_2D,((SurfaceOpenGL*)screen)->getTexture());\r
510 \r
511         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);\r
512         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);\r
513 \r
514         glUniform1i(osd_sampler_loc,0);\r
515 \r
516         glEnable(GL_BLEND);\r
517         glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_ONE);\r
518 \r
519 /*      glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),\r
520                         (GLvoid*)(((char*)osdvertices)+3*sizeof(GLfloat)));\r
521         glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),\r
522                         (GLvoid*)(((char*)osdvertices)+3*sizeof(GLfloat)+sizeof(OSDCOLOR)));*/\r
523         //glDisable(GL_LIGHTING);\r
524         //glEnable(GL_TEXTURE_2D);\r
525         //glEnable(GL_BLEND);\r
526     //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
527     //glDepthFunc(GL_ALWAYS);\r
528     //glDisable(GL_DEPTH_TEST);\r
529     //glDisable(GL_STENCIL_TEST);\r
530     //glDisable(GL_CULL_FACE);\r
531 \r
532 \r
533 \r
534 /*\r
535         glActiveTexture(GL_TEXTURE0);\r
536         glBindTexture(GL_TEXTURE_2D,((SurfaceOpenGL*)screen)->getTexture());\r
537         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);\r
538         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);*/\r
539 //      glUniform1i(mTextureUniformHandle, present);\r
540 \r
541 \r
542 \r
543         glDrawArrays(GL_TRIANGLE_STRIP, 0,  4);\r
544 \r
545         //glDrawElements(GL_TRIANGLES, sizeof(osdindices)/sizeof(osdindices[0]), GL_UNSIGNED_BYTE, 0);\r
546 \r
547 \r
548 \r
549 \r
550 /*      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), 0);\r
551         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),\r
552                                 (GLvoid*)(3*sizeof(GLfloat)));\r
553         glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX),\r
554                         (GLvoid*)(3*sizeof(GLfloat)+sizeof(OSDCOLOR)));*/\r
555 \r
556         //glDisable(GL_BLEND);\r
557         //glDisable(GL_TEXTURE_2D);\r
558         \r
559         //Show it to the user!\r
560         eglSwapBuffers(egl_display, egl_surface);\r
561 \r
562         EndPainting();\r
563 #ifdef BENCHMARK_FPS\r
564         num_benchmark_frames++;\r
565         if (getTimeMS()-last_benchmark_time>4000) {\r
566                 float fps=1000./(float)(getTimeMS()-last_benchmark_time);\r
567                 fps*=((float)num_benchmark_frames);\r
568                 num_benchmark_frames=0;\r
569                 Log::getInstance()->log("OSD", Log::NOTICE, "Current FPS %g", fps);\r
570                 last_benchmark_time=getTimeMS();\r
571 \r
572         }\r
573 \r
574 #endif\r
575 \r
576         \r
577 //      if (!external_driving) {\r
578 //              Sleep(4);//The User can wait for 4 milliseconds to see his changes\r
579 //      }\r
580 }\r
581 \r
582 bool OsdOpenGL::DoLost(){\r
583         /*\r
584         Log::getInstance()->log("OSD", Log::WARN, "Direct3D Device Lost! Reobtaining...");\r
585         ResetEvent(event);\r
586         if (external_driving && dsallocator!=NULL) {\r
587                 dsallocator->LostDevice(d3ddevice,d3d); //Propagate the information through DS\r
588         }\r
589         //First we free up all resources\r
590         Video* video = Video::getInstance();\r
591         ((SurfaceWin*)screen)->ReleaseSurface();\r
592         if (d3drtsurf) d3drtsurf->Release();\r
593     d3drtsurf=NULL;\r
594         D3DPRESENT_PARAMETERS d3dparas;\r
595         ZeroMemory(&d3dparas,sizeof(d3dparas));\r
596         d3dparas.BackBufferWidth=BACKBUFFER_WIDTH;\r
597         d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT;\r
598         d3dparas.Windowed=TRUE;\r
599         d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;\r
600 \r
601         if (swapsurf) {swapsurf->Release();swapsurf=NULL;};\r
602         if (swappy) {swappy->Release();swappy=NULL;};\r
603 \r
604         if (d3ddevice->Reset(&d3dparas)!=D3D_OK){\r
605                 return false;\r
606         }\r
607     d3ddevice->GetRenderTarget(0,&d3drtsurf);\r
608         if (d3ddevman) d3ddevman->ResetDevice(d3ddevice,dxvatoken);\r
609         //InitVertexBuffer();\r
610     //Redraw Views, Chris could you add a member function to BoxStack, so that\r
611         // I can cause it to completely redraw the Views?\r
612         // Otherwise the OSD would be distorted after Device Lost\r
613         // FIXME\r
614         \r
615         SetEvent(event);\r
616 \r
617 \r
618         screen->create(video->getScreenWidth(), video->getScreenHeight());\r
619         screen->display();*/\r
620         \r
621         return true;\r
622 \r
623 }\r
624 \r
625 \r
626 void OsdOpenGL::BeginPainting() {//We synchronize calls to d3d between different threads\r
627         glmutex.Lock();\r
628         if (initted) {\r
629                 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {\r
630                         Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %d",eglGetError());\r
631                         return;\r
632                 }\r
633         }\r
634 }\r
635 \r
636 void OsdOpenGL::EndPainting() {\r
637         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );\r
638         glmutex.Unlock();\r
639 }\r
640 \r
641 void OsdOpenGL::setExternalDriving(/*DsAllocator* dsall,*/unsigned int  width, unsigned height) {\r
642         /*\r
643         if (swappy)\r
644         {\r
645                 BeginPainting();\r
646                 d3ddevice->StretchRect(swapsurf,NULL,d3drtsurf,NULL,filter_type);\r
647                 LPDIRECT3DSWAPCHAIN9 temp=swappy;\r
648                 LPDIRECT3DSURFACE9 tempsurf=swapsurf;\r
649                 swappy=NULL;\r
650                 swapsurf=NULL;\r
651                 EndPainting();\r
652                 tempsurf->Release();\r
653                 temp->Release();\r
654         }\r
655 \r
656         if (dsall==NULL) {\r
657                 external_driving=false;\r
658                 dsallocator=NULL;       \r
659                 return;\r
660         }\r
661         WaitForSingleObject(event,INFINITE);//We will only return if we are initted\r
662         BeginPainting();\r
663 \r
664         if (width>BACKBUFFER_WIDTH || height>BACKBUFFER_HEIGHT) \r
665         {\r
666                 D3DPRESENT_PARAMETERS d3dparas;\r
667                 ZeroMemory(&d3dparas,sizeof(d3dparas));\r
668                 d3dparas.BackBufferWidth=width;\r
669                 d3dparas.BackBufferHeight=height;\r
670                 d3dparas.Windowed=TRUE;\r
671                 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;\r
672                 if (d3ddevice->CreateAdditionalSwapChain(&d3dparas,&swappy)!=D3D_OK){\r
673                         Log::getInstance()->log("OSD", Log::WARN, "Could not create Swap Chain!");\r
674                         //return 0;\r
675                 } else {\r
676                         swappy->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&swapsurf);\r
677                 }\r
678         Log::getInstance()->log("OSD", Log::INFO, "Create Additional Swap Chain %d %d!",width,height);\r
679         }\r
680 \r
681         dsallocator=dsall;\r
682         external_driving=true;\r
683         \r
684         EndPainting();*/\r
685 }\r
686 \r
687 void OsdOpenGL::Blank() {\r
688         BeginPainting();\r
689         glClearColor(0.15f, 0.25f, 0.35f, 1.0f); // change this to black after testing\r
690         glClear( GL_COLOR_BUFFER_BIT );\r
691         glClear( GL_DEPTH_BUFFER_BIT );\r
692         EndPainting();\r
693 }\r