1 /***************************************************************************
2 gui_render.cpp - description
3
4 The final render a frame. The external interface is the same
5 whatever the mean (RGB/YUV/Xv)
6 -------------------
7 begin : Thu Jan 3 2002
8 copyright : (C) 2002 by mean
9 email : fixounet@free.fr
10 ***************************************************************************/
11
12 /***************************************************************************
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 ***************************************************************************/
20
21 #include "config.h"
22 #include "ADM_default.h"
23 #include "DIA_coreToolkit.h"
24 #include "GUI_render.h"
25 #include "GUI_renderInternal.h"
26 #include "GUI_accelRender.h"
27 #include "GUI_nullRender.h"
28 #include "prefs.h"
29
30
31 extern VideoRenderBase *spawnSimpleRender();
32
33 #ifdef USE_XV
34 extern VideoRenderBase *spawnXvRender();
35 #endif
36
37 #ifdef USE_SDL
38 extern VideoRenderBase *spawnSdlRender();
39 #endif
40
41 #ifdef USE_VDPAU
42 extern VideoRenderBase *spawnVDPAURender();
43 #endif
44
45 #ifdef USE_LIBVA
46 extern VideoRenderBase *spawnLIBVARender();
47 #endif
48
49 #if defined (USE_OPENGL)
50 extern VideoRenderBase *RenderSpawnQtGl(void);
51 #endif
52 #if defined (USE_DXVA2)
53 extern VideoRenderBase *RenderSpawnDxva2(void);
54 #endif
55 #include "ADM_colorspace.h"
56 #include "DIA_uiTypes.h"
57
58 //_____________________________________
59 //_____________________________________
60 static VideoRenderBase *renderer=NULL;
61 static uint8_t *accelSurface=NULL;
62 static bool spawnRenderer(void);
63 //_______________________________________
64
65 static void *draw=NULL;
66 static uint32_t phyW=0,phyH=0; /* physical window size */
67 static float lastZoom=ZOOM_1_1;
68 static uint8_t _lock=0;
69
70 static const UI_FUNCTIONS_T *HookFunc=NULL;
71 static bool enableDraw=true;
72
73 refreshSB refreshCallback=NULL;
74 /**
75 * \fn renderGetName
76 * @param name
77 */
renderGetName(std::string & name)78 void renderGetName(std::string &name)
79 {
80 if(!renderer) name=std::string("None");
81 else name=std::string(renderer->getName());
82 }
83
84 /**
85 \fn renderHookRefreshRequest
86 \brief Hook the callback when a renderer requests a full redraw
87 */
renderHookRefreshRequest(refreshSB cb)88 bool renderHookRefreshRequest(refreshSB cb)
89 {
90 refreshCallback=cb;
91 return true;
92 }
93 /**
94 * \fn ADM_renderLibInit
95 * \brief Initialize the renderlib with the needed external functions
96 *
97 */
ADM_renderLibInit(const UI_FUNCTIONS_T * funcs)98 uint8_t ADM_renderLibInit(const UI_FUNCTIONS_T *funcs)
99 {
100 HookFunc=funcs;
101 ADM_assert(funcs->apiVersion==ADM_RENDER_API_VERSION_NUMBER);
102 return 1;
103 }
104 //**************************************
105 //**************************************
106 //**************************************
107 #define RENDER_CHECK(x) {ADM_assert(HookFunc);ADM_assert(HookFunc->x);}
MUI_getWindowInfo(void * draw,GUI_WindowInfo * xinfo)108 void MUI_getWindowInfo(void *draw, GUI_WindowInfo *xinfo)
109 {
110 RENDER_CHECK(UI_getWindowInfo);
111 HookFunc->UI_getWindowInfo(draw, xinfo);
112 }
MUI_updateDrawWindowSize(void * win,uint32_t w,uint32_t h)113 static void MUI_updateDrawWindowSize(void *win,uint32_t w,uint32_t h)
114 {
115 RENDER_CHECK(UI_updateDrawWindowSize);
116 HookFunc->UI_updateDrawWindowSize(win,w,h);
117 }
MUI_getPreferredRender(void)118 static ADM_RENDER_TYPE MUI_getPreferredRender(void)
119 {
120 RENDER_CHECK(UI_getPreferredRender);
121 return HookFunc->UI_getPreferredRender();
122 }
MUI_getDrawWidget(void)123 void *MUI_getDrawWidget(void)
124 {
125 RENDER_CHECK(UI_getDrawWidget);
126 return HookFunc->UI_getDrawWidget();
127 }
128
129 //**************************************
130 //**************************************
131 //**************************************
132
133 /**
134 Render init, initialize internals. Constuctor like function
135
136 */
renderInit(void)137 uint8_t renderInit( void )
138 {
139 draw=MUI_getDrawWidget( );
140 enableDraw=false;
141 return 1;
142 }
143
renderDestroy(void)144 void renderDestroy(void)
145 {
146 ADM_info("Cleaning up Render\n");
147 if(renderer)
148 {
149 renderer->stop();
150 delete renderer;
151 renderer=NULL;
152 }
153 enableDraw=false;
154 }
155
156 /**
157 \fn renderLock
158 \brief Take the weak lock (i.e. not threadsafe)
159 */
renderLock(void)160 uint8_t renderLock(void)
161 {
162 ADM_assert(!_lock);
163 _lock=1;
164 return 1;
165 }
renderUnlock(void)166 uint8_t renderUnlock(void)
167 {
168 ADM_assert(_lock);
169 _lock=0;
170 return 1;
171 }
172
173 /**
174 Warn the renderer that the display size is changing
175
176 */
177 //----------------------------------------
renderDisplayResize(uint32_t w,uint32_t h,float zoom)178 uint8_t renderDisplayResize(uint32_t w, uint32_t h, float zoom)
179 {
180 bool create=false;
181 enableDraw=false;
182 ADM_info("Render to %" PRIu32"x%" PRIu32" zoom=%.4f, old one =%d x %d, zoom=%.4f, renderer=%p\n",w,h,zoom,phyW,phyH,lastZoom,renderer);
183 // Check if something has changed...
184
185
186 if(renderer && w==phyW && h==phyH && zoom==lastZoom)
187 {
188 ADM_info(" No change, nothing to do\n");
189 return true;
190 }
191
192 if(!renderer || (w!=phyW || h!=phyH))
193 {
194 if(renderer)
195 {
196 renderer->stop();
197 delete renderer;
198 renderer=NULL;
199 }
200 phyW=w;
201 phyH=h;
202 lastZoom=zoom;
203 if(w && h)
204 spawnRenderer();
205 }else // only zoom changed
206 {
207 renderer->changeZoom(zoom);
208 }
209 // Resize widget to be the same as input after zoom
210 lastZoom=zoom;
211 MUI_updateDrawWindowSize(draw,(uint32_t)((float)w*zoom),(uint32_t)((float)h*zoom));
212 if(w && h)
213 renderCompleteRedrawRequest();
214 UI_purge();
215 return 1;
216 }
217 /**
218 Update the image and render it
219 The width and hiehgt must NOT have changed
220
221 */
222 //----------------------------------------
renderUpdateImage(ADMImage * image)223 uint8_t renderUpdateImage(ADMImage *image)
224 {
225 if(!renderer)
226 {
227 ADM_warning("Render update image without renderer\n");
228 return 0;
229 }
230 ADM_assert(!_lock);
231 enableDraw=true;
232 if(renderer->getPreferedImage()!=image->refType)
233 image->hwDownloadFromRef();
234
235 renderer->displayImage(image);
236 return 1;
237 }
238 /**
239 Refresh the image from internal buffer / last image
240 Used for example as call back for X11 events
241
242 */
243 //_______________________________________________
renderRefresh(void)244 uint8_t renderRefresh(void)
245 {
246 if(_lock) return 1;
247 if(enableDraw==false) return true;
248 if(renderer)
249 renderer->refresh();
250 return 1;
251 }
252 /**
253 \fn renderCompleteRedrawRequest
254 \brief ask the *caller* to redraw, whereas expose/refresh asks the renderer to refresh
255 */
renderCompleteRedrawRequest(void)256 bool renderCompleteRedrawRequest(void)
257 {
258 ADM_info("RedrawRequest\n");
259 if(enableDraw==false) return true;
260 if(refreshCallback)
261 refreshCallback();
262 return true;
263 }
264 /**
265 \fn renderExpose
266 */
renderExpose(void)267 uint8_t renderExpose(void)
268 {
269 if(enableDraw==false) return true;
270 renderRefresh();
271 return 1;
272 }
273 /**
274 \fn spawnRenderer
275 \brief Create renderer according to prefs
276 */
277 #if ADM_UI_TYPE_BUILD == ADM_UI_CLI
278
spawnRenderer(void)279 bool spawnRenderer(void)
280 {
281 renderer=new nullRender();
282 return true;
283 }
284 #else
285
286 #define TRY_RENDERER_INTERNAL(clss,create,name) \
287 renderer=create clss(); \
288 r=renderer->init(&xinfo,phyW,phyH,lastZoom); \
289 if(!r) \
290 { \
291 delete renderer; \
292 renderer=NULL; \
293 ADM_warning(name" init failed\n"); \
294 }\
295 else \
296 { \
297 ADM_info(name" init ok\n"); \
298 }
299 //#define TRY_RENDERER_CLASS(clss,name) TRY_RENDERER_INTERNAL(clss,new,name)
300 //#define TRY_RENDERER_FUNC(func,name) TRY_RENDERER_INTERNAL(func,,name)
301 #define TRY_RENDERER_SPAWN(spawn,name) TRY_RENDERER_INTERNAL(spawn,,name)
302 /**
303 *
304 * @param renderName
305 * @return
306 */
spawnRenderer(void)307 bool spawnRenderer(void)
308 {
309 int prefRenderer=MUI_getPreferredRender();
310 bool r=false;
311
312 GUI_WindowInfo xinfo;
313 MUI_getWindowInfo(draw, &xinfo);
314 switch(prefRenderer)
315 {
316 #if defined(USE_DXVA2)
317 case RENDER_DXVA2:
318 {
319 TRY_RENDERER_SPAWN(RenderSpawnDxva2,"Dxva2");
320 break;
321 }
322 #endif
323 #if defined(USE_OPENGL)
324 case RENDER_QTOPENGL:
325 {
326 bool hasOpenGl=false;
327 prefs->get(FEATURES_ENABLE_OPENGL,&hasOpenGl);
328 if(!hasOpenGl)
329 {
330 ADM_warning("OpenGl is disabled\n");
331 renderer=NULL;
332 }else
333 {
334 TRY_RENDERER_SPAWN(RenderSpawnQtGl,"QtGl");
335 }
336 break;
337 }
338 #endif
339
340 #if defined(USE_VDPAU)
341 case RENDER_VDPAU:
342 TRY_RENDERER_SPAWN(spawnVDPAURender,"VDPAU")
343 break;
344 #endif
345 #if defined(USE_LIBVA)
346 case RENDER_LIBVA:
347 TRY_RENDERER_SPAWN(spawnLIBVARender,"LIBVA")
348 break;
349 #endif
350
351 #if defined(USE_XV)
352 case RENDER_XV:
353 TRY_RENDERER_SPAWN(spawnXvRender,"Xv")
354 break;
355 #endif
356
357 #if defined(USE_SDL)
358 case RENDER_SDL:
359 TRY_RENDERER_SPAWN(spawnSdlRender,"SDL")
360 break;
361 #endif
362 }
363 if(!renderer)
364 {
365 TRY_RENDERER_SPAWN(spawnSimpleRender,"simpleRenderer");
366 ADM_assert(renderer);
367 }
368 return true;
369 }
370 #endif
371
372 /**
373 \fn
374 */
renderStartPlaying(void)375 uint8_t renderStartPlaying( void )
376 {
377
378 return 1;
379 }
380
381 /**
382 \fn renderStopPlaying
383 */
renderStopPlaying(void)384 uint8_t renderStopPlaying( void )
385 {
386
387 return true;
388 }
389 /**
390 \fn renderExposeEventFromUI
391 \brief retrurn true if UI(gtk/qt) should handle redraw
392 */
renderExposeEventFromUI(void)393 bool renderExposeEventFromUI(void)
394 {
395 if(!renderer) return true;
396 if(renderer->usingUIRedraw()==true) return true;
397 renderer->refresh();
398 return false;
399
400 }
401 /**
402 \fn renderGetPreferedImageFormat
403 \brief get the prefered hw accelerated image format (NONE,VDPAU,...)
404 */
renderGetPreferedImageFormat(void)405 ADM_HW_IMAGE renderGetPreferedImageFormat(void)
406 {
407 if(!renderer) return ADM_HW_NONE;
408 return renderer->getPreferedImage();
409 }
410
411 //***************************************
412 /**
413 \fn calcDisplayFromZoom
414 */
calcDisplayFromZoom(float zoom)415 bool VideoRenderBase::calcDisplayFromZoom(float zoom)
416 {
417 displayWidth=(uint32_t)((float)imageWidth * zoom);
418 displayHeight=(uint32_t)((float)imageHeight * zoom);
419 return true;
420 }
421
422 /**
423 \fn baseInit
424 */
baseInit(uint32_t w,uint32_t h,float zoom)425 bool VideoRenderBase::baseInit(uint32_t w, uint32_t h, float zoom)
426 {
427 imageWidth=w;
428 imageHeight=h;
429 currentZoom=zoom;
430 calcDisplayFromZoom(zoom);
431 return true;
432 }
433
434 /**
435 * \fn renderClearInstance
436 * \brief warn render that the renderer has been deleted by low level (window manager)
437 * Would be prettier to do it with refCounting
438 * @return
439 */
renderClearInstance(void)440 bool renderClearInstance(void)
441 {
442 renderer=NULL;
443 return true;
444 }
445
446 //EOF
447