PANDORA: Make GLES context compatible with latest driver (FB only, no X11)
[mupen64plus-pandora.git] / source / rice_gles / src / eglport.c
CommitLineData
d07c171f 1/**
2 *
3 * EGLPORT.C
4 * Copyright (C) 2011-2013 Scott R. Smith
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 */
25
26#include "eglport.h"
27
28#include <stdio.h>
29#include <stdlib.h>
30
31#define USE_EGL_SDL 1
32#define USE_GLES1 1
33
34#if defined(USE_EGL_SDL)
35#include "SDL.h"
36#include "SDL_syswm.h"
37SDL_SysWMinfo sysWmInfo; /** Holds our X Display/Window information */
38#endif /* USE_EGL_SDL */
39
40#if defined(PANDORA) /* Pandora VSync Support */
41#include <unistd.h>
42#include <fcntl.h>
43#include <sys/ioctl.h>
44#include <linux/fb.h>
45
46#ifndef FBIO_WAITFORVSYNC
47#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
48#endif
49int fbdev = -1;
50
51#elif defined(RPI)
52#include "bcm_host.h"
53#endif /* PANDORA */
54
55enum EGL_RENDER_T {
56 RENDER_RAW=0, /** Sets render mode to raw or framebuffer mode. */
57 RENDER_SDL, /** Sets render mode to X11/SDL mode. */
58 RENDER_TOTAL
59};
60
61enum EGL_SETTINGS_T {
62 CFG_MODE=0, /** Render mode for EGL 0=RAW 1=SDL. */
63 CFG_VSYNC, /** Controls system vsync if available. */
64 CFG_FSAA, /** Number of samples for full screen AA. 0 is off, 2/4 samples. */
65 CFG_FPS, /** Calculate and report frame per second. */
66 CFG_RED_SIZE, /** Number of bits of Red in the color buffer. */
67 CFG_GREEN_SIZE, /** Number of bits of Green in the color buffer. */
68 CFG_BLUE_SIZE, /** Number of bits of Blue in the color buffer. */
69 CFG_ALPHA_SIZE, /** Number of bits of Alpha in the color buffer. */
70 CFG_DEPTH_SIZE, /** Number of bits of Z in the depth buffer. */
71 CFG_BUFFER_SIZE, /** The total color component bits in the color buffer. */
72 CFG_STENCIL_SIZE, /** Number of bits of Stencil in the stencil buffer. */
73 CFG_TOTAL /** Total number of settings. */
74};
75
76NativeDisplayType nativeDisplay = 0; /** Reference to the systems native display */
77NativeWindowType nativeWindow = 0; /** Reference to the systems native window */
78EGLint eglSettings[CFG_TOTAL]; /** Stores setting values. */
79EGLDisplay eglDisplay = NULL; /** Reference to the EGL display */
80EGLConfig eglConfig = NULL; /** Reference to the EGL config */
81EGLContext eglContext = NULL; /** Reference to the EGL context */
82EGLSurface eglSurface = NULL; /** Reference to the EGL surface */
83
84#define totalConfigsIn 5 /** Total number of configurations to request */
85EGLint totalConfigsFound = 0; /** Total number of configurations matching attributes */
86EGLConfig eglConfigs[totalConfigsIn]; /** Structure containing references to matching configurations */
87
88uint32_t fpsCount = 0; /** Total number of frames counted */
89uint32_t fpsTime = 0; /** Start time of frame count measurment */
90
91int8_t eglColorbits = 0;
92int8_t eglDepthbits = 0;
93int8_t eglStencilbits = 0;
94
95
96/** Private API */
97void OpenCfg ( const char* file );
98int8_t ConfigureEGL ( EGLConfig config );
99int8_t FindEGLConfigs ( void );
100int8_t CheckEGLErrors ( const char* file, uint16_t line );
101
102int8_t GetNativeDisplay ( void );
103int8_t GetNativeWindow ( uint16_t width, uint16_t height );
104void FreeNativeDisplay ( void );
105void FreeNativeWindow ( void );
106
107void Platform_Open ( void );
108void Platform_Close ( void );
109void Platform_VSync ( void );
110uint32_t Platform_GetTicks ( void );
111
112/** @brief Release all EGL and system resources
113 */
114void EGL_Close( void )
115{
116 /* Release EGL resources */
117 if (eglDisplay != NULL)
118 {
119 peglMakeCurrent( eglDisplay, NULL, NULL, EGL_NO_CONTEXT );
120 if (eglContext != NULL) {
121 peglDestroyContext( eglDisplay, eglContext );
122 }
123 if (eglSurface != NULL) {
124 peglDestroySurface( eglDisplay, eglSurface );
125 }
126 peglTerminate( eglDisplay );
127 }
128
129 eglSurface = NULL;
130 eglContext = NULL;
131 eglDisplay = NULL;
132
133 eglColorbits = 0;
134 eglDepthbits = 0;
135 eglStencilbits = 0;
136
137 /* Release platform resources */
138 FreeNativeWindow();
139 FreeNativeDisplay();
140 Platform_Close();
141
142 CheckEGLErrors( __FILE__, __LINE__ );
143
144 printf( "EGLport: Closed\n" );
145}
146
147/** @brief Swap the surface buffer onto the display
148 */
149void EGL_SwapBuffers( void )
150{
151 if (eglSettings[CFG_VSYNC] != 0) {
152 Platform_VSync();
153 }
154
155 peglSwapBuffers( eglDisplay, eglSurface );
156
157 if (eglSettings[CFG_FPS] != 0) {
158 fpsCount++;
159
160 if (fpsTime - Platform_GetTicks() >= 1000)
161 {
162 printf( "EGLport: %d fps\n", fpsCount );
163 fpsTime = Platform_GetTicks();
164 fpsCount = 0;
165 }
166 }
167}
168
169/** @brief Obtain the system display and initialize EGL
170 * @param width : desired pixel width of the window (not used by all platforms)
171 * @param height : desired pixel height of the window (not used by all platforms)
172 * @return : 0 if the function passed, else 1
173 */
174int8_t EGL_Open( uint16_t width, uint16_t height )
175{
176 EGLint eglMajorVer, eglMinorVer;
177 EGLBoolean result;
178 uint32_t configIndex = 0;
179 const char* output;
180
181 static const EGLint contextAttribs[] =
182 {
183#if defined(USE_GLES2)
184 EGL_CONTEXT_CLIENT_VERSION, 2,
185#endif
186 EGL_NONE
187 };
188
189#if defined(DEBUG)
190 printf( "EGLport Warning: DEBUG is enabled which may effect performance\n" );
191#endif
192
193 /* Check that system is not open */
194 if (eglDisplay != NULL || eglContext != NULL || eglSurface != NULL)
195 {
196 printf( "EGLport ERROR: EGL system is already open!\n" );
197 return 1;
198 }
199
200 /* Check for the cfg file to alternative settings */
201 OpenCfg( "eglport.cfg" );
202
203 /* Setup any platform specific bits */
204 Platform_Open();
205
206 printf( "EGLport: Opening EGL display\n" );
207 if (GetNativeDisplay() != 0)
208 {
209 printf( "EGLport ERROR: Unable to obtain native display!\n" );
210 return 1;
211 }
212
213 eglDisplay = peglGetDisplay( nativeDisplay );
214 if (eglDisplay == EGL_NO_DISPLAY)
215 {
216 CheckEGLErrors( __FILE__, __LINE__ );
217 printf( "EGLport ERROR: Unable to create EGL display.\n" );
218 return 1;
219 }
220
221 printf( "EGLport: Initializing\n" );
222 result = peglInitialize( eglDisplay, &eglMajorVer, &eglMinorVer );
223 if (result != EGL_TRUE )
224 {
225 CheckEGLErrors( __FILE__, __LINE__ );
226 printf( "EGLport ERROR: Unable to initialize EGL display.\n" );
227 return 1;
228 }
229
230 /* Get EGL Library Information */
231 printf( "EGL Implementation Version: Major %d Minor %d\n", eglMajorVer, eglMinorVer );
232 output = peglQueryString( eglDisplay, EGL_VENDOR );
233 printf( "EGL_VENDOR: %s\n", output );
234 output = peglQueryString( eglDisplay, EGL_VERSION );
235 printf( "EGL_VERSION: %s\n", output );
236 output = peglQueryString( eglDisplay, EGL_EXTENSIONS );
237 printf( "EGL_EXTENSIONS: %s\n", output );
238
239 if (FindEGLConfigs() != 0)
240 {
241 printf( "EGLport ERROR: Unable to configure EGL. See previous error.\n" );
242 return 1;
243 }
244
245 printf( "EGLport: Using Config %d\n", configIndex );
246#if defined(EGL_VERSION_1_2)
247 /* Bind GLES and create the context */
248 printf( "EGLport: Binding API\n" );
249 result = peglBindAPI( EGL_OPENGL_ES_API );
250 if ( result == EGL_FALSE )
251 {
252 CheckEGLErrors( __FILE__, __LINE__ );
253 printf( "EGLport ERROR: Could not bind EGL API.\n" );
254 return 1;
255 }
256#endif /* EGL_VERSION_1_2 */
257
258 printf( "EGLport: Creating Context\n" );
259 eglContext = peglCreateContext( eglDisplay, eglConfigs[configIndex], NULL, contextAttribs );
260 if (eglContext == EGL_NO_CONTEXT)
261 {
262 CheckEGLErrors( __FILE__, __LINE__ );
263 printf( "EGLport ERROR: Unable to create GLES context!\n");
264 return 1;
265 }
266
267 printf( "EGLport: Creating window surface\n" );
268 if (GetNativeWindow( width, height ) != 0)
269 {
270 printf( "EGLport ERROR: Unable to obtain native window!\n" );
271 return 1;
272 }
273
274 eglSurface = peglCreateWindowSurface( eglDisplay, eglConfigs[configIndex], nativeWindow, 0 );
275 if (eglSurface == EGL_NO_SURFACE)
276 {
277 CheckEGLErrors( __FILE__, __LINE__ );
278 printf( "EGLport ERROR: Unable to create EGL surface!\n" );
279 return 1;
280 }
281
282 printf( "EGLport: Making Current\n" );
283 result = peglMakeCurrent( eglDisplay, eglSurface, eglSurface, eglContext );
284 if (result != EGL_TRUE)
285 {
286 CheckEGLErrors( __FILE__, __LINE__ );
287 printf( "EGLport ERROR: Unable to make GLES context current\n" );
288 return 1;
289 }
290
291 {
292 EGLint color, depth, stencil;
293 eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_BUFFER_SIZE, &color);
294 eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_DEPTH_SIZE, &depth);
295 eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_STENCIL_SIZE, &stencil);
296 eglColorbits = (color==16)?5:8; //quick hack
297 eglDepthbits = depth;
298 eglStencilbits = stencil;
299 }
300
301 printf( "EGLport: Setting swap interval\n" );
302 peglSwapInterval( eglDisplay, (eglSettings[CFG_VSYNC] > 0) ? 1 : 0 );
303
304 printf( "EGLport: Complete\n" );
305
306 CheckEGLErrors( __FILE__, __LINE__ );
307
308 return 0;
309}
310
311/** @brief Read settings that configure how to use EGL
312 * @param file : name of the config file
313 */
314void OpenCfg ( const char* file )
315{
316 #define MAX_STRING 20
317 #define MAX_SIZE 100
318 uint8_t i;
319 FILE* fp = NULL;
320 char* location = NULL;
321 char eglStrings[CFG_TOTAL][MAX_STRING];
322 char buffer[MAX_SIZE];
323
324 strncpy( eglStrings[CFG_MODE], "egl_mode=", MAX_STRING );
325 strncpy( eglStrings[CFG_VSYNC], "use_vsync=", MAX_STRING );
326 strncpy( eglStrings[CFG_FSAA], "use_fsaa=", MAX_STRING );
327 strncpy( eglStrings[CFG_RED_SIZE], "size_red=", MAX_STRING );
328 strncpy( eglStrings[CFG_GREEN_SIZE], "size_green=", MAX_STRING );
329 strncpy( eglStrings[CFG_BLUE_SIZE], "size_blue=", MAX_STRING );
330 strncpy( eglStrings[CFG_ALPHA_SIZE], "size_alpha=", MAX_STRING );
331 strncpy( eglStrings[CFG_DEPTH_SIZE], "size_depth=", MAX_STRING );
332 strncpy( eglStrings[CFG_BUFFER_SIZE], "size_buffer=", MAX_STRING );
333 strncpy( eglStrings[CFG_STENCIL_SIZE], "size_stencil=", MAX_STRING );
334
335 /* Set defaults */
06190a2d 336//#if defined(USE_EGL_SDL)
337// eglSettings[CFG_MODE] = RENDER_SDL;
338//#else
d07c171f 339 eglSettings[CFG_MODE] = RENDER_RAW;
06190a2d 340//#endif
d07c171f 341 eglSettings[CFG_VSYNC] = 0;
342 eglSettings[CFG_FSAA] = 0;
343 eglSettings[CFG_FPS] = 0;
344 eglSettings[CFG_RED_SIZE] = 5;
345 eglSettings[CFG_GREEN_SIZE] = 6;
346 eglSettings[CFG_BLUE_SIZE] = 5;
347 eglSettings[CFG_ALPHA_SIZE] = 0;
348 eglSettings[CFG_DEPTH_SIZE] = 16;
349 eglSettings[CFG_BUFFER_SIZE] = 16;
350 eglSettings[CFG_STENCIL_SIZE] = 0;
351
352 /* Parse INI file */
353 fp = fopen( file, "r");
354 if (fp != NULL)
355 {
356 while (fgets( buffer, MAX_SIZE, fp ) != NULL)
357 {
358 for (i=0; i<CFG_TOTAL; i++)
359 {
360 location = strstr( buffer, eglStrings[i] );
361 if (location != NULL)
362 {
363 eglSettings[i] = atol( location+strlen( eglStrings[i] ) );
364 printf( "EGLport: %s set to %d.\n", eglStrings[i], eglSettings[i] );
365 break;
366 }
367 }
368 }
369
370 fclose( fp );
371 }
372 else
373 {
06190a2d 374 printf( "EGL NOTICE: Unable to read ini settings from file '%s'. Using defaults\n", file );
d07c171f 375 }
376}
377
378/** @brief Find a EGL configuration tht matches the defined attributes
379 * @return : 0 if the function passed, else 1
380 */
381int8_t FindEGLConfigs( void )
382{
383 EGLBoolean result;
384 int attrib = 0;
385 EGLint ConfigAttribs[23];
386
387 ConfigAttribs[attrib++] = EGL_RED_SIZE; /* 1 */
388 ConfigAttribs[attrib++] = eglSettings[CFG_RED_SIZE]; /* 2 */
389 ConfigAttribs[attrib++] = EGL_GREEN_SIZE; /* 3 */
390 ConfigAttribs[attrib++] = eglSettings[CFG_GREEN_SIZE]; /* 4 */
391 ConfigAttribs[attrib++] = EGL_BLUE_SIZE; /* 5 */
392 ConfigAttribs[attrib++] = eglSettings[CFG_BLUE_SIZE]; /* 6 */
393 ConfigAttribs[attrib++] = EGL_ALPHA_SIZE; /* 7 */
394 ConfigAttribs[attrib++] = eglSettings[CFG_ALPHA_SIZE]; /* 8 */
395 ConfigAttribs[attrib++] = EGL_DEPTH_SIZE; /* 9 */
396 ConfigAttribs[attrib++] = eglSettings[CFG_DEPTH_SIZE]; /* 10 */
397 ConfigAttribs[attrib++] = EGL_BUFFER_SIZE; /* 11 */
398 ConfigAttribs[attrib++] = eglSettings[CFG_BUFFER_SIZE]; /* 12 */
399 ConfigAttribs[attrib++] = EGL_STENCIL_SIZE; /* 13 */
400 ConfigAttribs[attrib++] = eglSettings[CFG_STENCIL_SIZE]; /* 14 */
401 ConfigAttribs[attrib++] = EGL_SURFACE_TYPE; /* 15 */
402 ConfigAttribs[attrib++] = EGL_WINDOW_BIT; /* 16 */
403#if defined(EGL_VERSION_1_2)
404 ConfigAttribs[attrib++] = EGL_RENDERABLE_TYPE; /* 17 */
405#if defined(USE_GLES1)
406 ConfigAttribs[attrib++] = EGL_OPENGL_ES_BIT;
407#elif defined(USE_GLES2)
408 ConfigAttribs[attrib++] = EGL_OPENGL_ES2_BIT; /* 18 */
409#endif /* USE_GLES1 */
410#endif /* EGL_VERSION_1_2 */
411 ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS; /* 19 */
412 ConfigAttribs[attrib++] = (eglSettings[CFG_FSAA] > 0) ? 1 : 0; /* 20 */
413 ConfigAttribs[attrib++] = EGL_SAMPLES; /* 21 */
414 ConfigAttribs[attrib++] = eglSettings[CFG_FSAA]; /* 22 */
415 ConfigAttribs[attrib++] = EGL_NONE; /* 23 */
416
417 result = peglChooseConfig( eglDisplay, ConfigAttribs, eglConfigs, totalConfigsIn, &totalConfigsFound );
418 if (result != EGL_TRUE || totalConfigsFound == 0)
419 {
420 CheckEGLErrors( __FILE__, __LINE__ );
421 printf( "EGLport ERROR: Unable to query for available configs, found %d.\n", totalConfigsFound );
422 return 1;
423 }
424 printf( "EGLport: Found %d available configs\n", totalConfigsFound );
425
426 return 0;
427}
428
429/** @brief Error checking function
430 * @param file : string reference that contains the source file that the check is occuring in
431 * @param line : numeric reference that contains the line number that the check is occuring in
432 * @return : 0 if the function passed, else 1
433 */
434int8_t CheckEGLErrors( const char* file, uint16_t line )
435{
436 EGLenum error;
437 const char* errortext;
438 const char* description;
439
440 error = eglGetError();
441
442 if (error != EGL_SUCCESS && error != 0)
443 {
444 switch (error)
445 {
446 case EGL_NOT_INITIALIZED:
447 errortext = "EGL_NOT_INITIALIZED.";
448 description = "EGL is not or could not be initialized, for the specified display.";
449 break;
450 case EGL_BAD_ACCESS:
451 errortext = "EGL_BAD_ACCESS EGL";
452 description = "cannot access a requested resource (for example, a context is bound in another thread).";
453 break;
454 case EGL_BAD_ALLOC:
455 errortext = "EGL_BAD_ALLOC EGL";
456 description = "failed to allocate resources for the requested operation.";
457 break;
458 case EGL_BAD_ATTRIBUTE:
459 errortext = "EGL_BAD_ATTRIBUTE";
460 description = "An unrecognized attribute or attribute value was passed in anattribute list.";
461 break;
462 case EGL_BAD_CONFIG:
463 errortext = "EGL_BAD_CONFIG";
464 description = "An EGLConfig argument does not name a valid EGLConfig.";
465 break;
466 case EGL_BAD_CONTEXT:
467 errortext = "EGL_BAD_CONTEXT";
468 description = "An EGLContext argument does not name a valid EGLContext.";
469 break;
470 case EGL_BAD_CURRENT_SURFACE:
471 errortext = "EGL_BAD_CURRENT_SURFACE";
472 description = "The current surface of the calling thread is a window, pbuffer,or pixmap that is no longer valid.";
473 break;
474 case EGL_BAD_DISPLAY:
475 errortext = "EGL_BAD_DISPLAY";
476 description = "An EGLDisplay argument does not name a valid EGLDisplay.";
477 break;
478 case EGL_BAD_MATCH:
479 errortext = "EGL_BAD_MATCH";
480 description = "Arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.";
481 break;
482 case EGL_BAD_NATIVE_PIXMAP:
483 errortext = "EGL_BAD_NATIVE_PIXMAP";
484 description = "An EGLNativePixmapType argument does not refer to a validnative pixmap.";
485 break;
486 case EGL_BAD_NATIVE_WINDOW:
487 errortext = "EGL_BAD_NATIVE_WINDOW";
488 description = "An EGLNativeWindowType argument does not refer to a validnative window.";
489 break;
490 case EGL_BAD_PARAMETER:
491 errortext = "EGL_BAD_PARAMETER";
492 description = "One or more argument values are invalid.";
493 break;
494 case EGL_BAD_SURFACE:
495 errortext = "EGL_BAD_SURFACE";
496 description = "An EGLSurface argument does not name a valid surface (window,pbuffer, or pixmap) configured for rendering";
497 break;
498 case EGL_CONTEXT_LOST:
499 errortext = "EGL_CONTEXT_LOST";
500 description = "A power management event has occurred. The application mustdestroy all contexts and reinitialise client API state and objects to continue rendering.";
501 break;
502 default:
503 errortext = "Unknown EGL Error";
504 description = "";
505 break;
506 }
507
508 printf( "EGLport ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n Description: %s\n", file, line, errortext, error, description );
509 return 1;
510 }
511
512 return 0;
513}
514
515/** @brief Obtain a reference to the system's native display
516 * @param window : pointer to save the display reference
517 * @return : 0 if the function passed, else 1
518 */
519int8_t GetNativeDisplay( void )
520{
521 if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */
522 {
523 printf( "EGLport: Using EGL_DEFAULT_DISPLAY\n" );
524 nativeDisplay = EGL_DEFAULT_DISPLAY;
525 }
526 else if (eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */
527 {
528#if defined(USE_EGL_SDL)
529 printf( "EGLport: Opening SDL/X11 display\n" );
530 SDL_VERSION(&sysWmInfo.version);
531 SDL_GetWMInfo(&sysWmInfo);
532 nativeDisplay = (EGLNativeDisplayType)sysWmInfo.info.x11.display;
533
534 if (nativeDisplay == 0)
535 {
536 printf( "EGLport ERROR: unable to get display!\n" );
537 return 1;
538 }
539#else
540 printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
541#endif
542 }
543
544 return 0;
545}
546
547/** @brief Obtain a reference to the system's native window
548 * @param width : desired pixel width of the window (not used by all platforms)
549 * @param height : desired pixel height of the window (not used by all platforms)
550 * @return : 0 if the function passed, else 1
551 */
552int8_t GetNativeWindow( uint16_t width, uint16_t height )
553{
554 nativeWindow = 0;
555
556#if defined(WIZ) || defined(CAANOO)
557
558 nativeWindow = (NativeWindowType)malloc(16*1024);
559
560 if(nativeWindow == NULL) {
561 printf( "EGLport ERROR: Memory for window Failed\n" );
562 return 1;
563 }
564
565#elif defined(RPI)
566
567 EGLBoolean result;
568 uint32_t screen_width, screen_height;
569 static EGL_DISPMANX_WINDOW_T nativewindow;
570 DISPMANX_ELEMENT_HANDLE_T dispman_element;
571 DISPMANX_DISPLAY_HANDLE_T dispman_display;
572 DISPMANX_UPDATE_HANDLE_T dispman_update;
573 VC_RECT_T dst_rect;
574 VC_RECT_T src_rect;
575
576 /* create an EGL window surface */
577 result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
578 if(result < 0) {
579 printf( "EGLport ERROR: RPi graphicget_display_size failed\n" );
580 return 1;
581 }
582
583 dst_rect.x = 0;
584 dst_rect.y = 0;
585 dst_rect.width = screen_width;
586 dst_rect.height = screen_height;
587
588 src_rect.x = 0;
589 src_rect.y = 0;
590 src_rect.width = width << 16;
591 src_rect.height = height << 16;
592
593 dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
594 dispman_update = vc_dispmanx_update_start( 0 );
595 dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
596 0 /*layer*/, &dst_rect, 0 /*src*/,
597 &src_rect, DISPMANX_PROTECTION_NONE, (VC_DISPMANX_ALPHA_T*)0 /*alpha*/, (DISPMANX_CLAMP_T*)0 /*clamp*/, (DISPMANX_TRANSFORM_T)0 /*transform*/);
598
599 nativewindow.element = dispman_element;
600 nativewindow.width = screen_width;
601 nativewindow.height = screen_height;
602 vc_dispmanx_update_submit_sync( dispman_update );
603
604 nativeWindow = (NativeWindowType)&nativewindow;
605
606#else /* default */
607
608 if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */
609 {
610 nativeWindow = 0;
611 }
612 else if(eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */
613 {
614#if defined(USE_EGL_SDL)
615 /* SDL_GetWMInfo is populated when display was opened */
616 nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window;
617
618 if (nativeWindow == 0)
619 {
620 printf( "EGLport ERROR: unable to get window!\n" );
621 return 1;
622 }
623#else
624 printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
625#endif
626 }
627 else
628 {
629 printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] );
630 return 1;
631 }
632
633#endif /* WIZ / CAANOO */
634
635 return 0;
636}
637
638/** @brief Release the system's native display
639 */
640void FreeNativeDisplay( void )
641{
642}
643
644/** @brief Release the system's native window
645 */
646void FreeNativeWindow( void )
647{
648#if defined(WIZ) || defined(CAANOO)
649 if (nativeWindow != NULL) {
650 free( nativeWindow );
651 }
652 nativeWindow = NULL;
653#endif /* WIZ / CAANOO */
654}
655
656/** @brief Open any system specific resources
657 */
658void Platform_Open( void )
659{
660#if defined(PANDORA)
661 /* Pandora VSync */
662 fbdev = open( "/dev/fb0", O_RDONLY /* O_RDWR */ );
663 if ( fbdev < 0 ) {
664 printf( "EGLport ERROR: Couldn't open /dev/fb0 for Pandora Vsync\n" );
665 }
666#elif defined(RPI)
667 bcm_host_init();
668#endif /* PANDORA */
669}
670
671/** @brief Release any system specific resources
672 */
673void Platform_Close( void )
674{
675#if defined(PANDORA)
676 /* Pandora VSync */
677 close( fbdev );
678 fbdev = -1;
679#endif /* PANDORA */
680}
681
682/** @brief Check the systems vsync state
683 */
684void Platform_VSync( void )
685{
686#if defined(PANDORA)
687 /* Pandora VSync */
688 if (fbdev >= 0) {
689 int arg = 0;
690 ioctl( fbdev, FBIO_WAITFORVSYNC, &arg );
691 }
692#endif /* PANDORA */
693}
694
695/** @brief Get the system tick time (ms)
696 */
697uint32_t Platform_GetTicks( void )
698{
699 uint32_t ticks = 0;
700#if defined(USE_EGL_SDL)
701 ticks = SDL_GetTicks();
702#else
703 printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
704#endif
705 return ticks;
706}