Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 2357:ad4a291c85ab gsoc2008_iphone
Added support for OpenGL ES and UIKit Video Driver:
- included SDL_renderer_gles.h
- added UIKit Video driver bootstrap declaration
- added property "retained_backing" to gl_config structure. Having retained backing means your video buffers can't be overwritten by other applications between drawing frames. By default, this is enabled. I wanted to give the option to disable this on iPhone because it increases performance greatly.
- modified SDL_GetAttribute and SDL_SetAttribute function for OpenGL ES support. OpenGL ES does not have support for accumulation buffers, and is always double buffered, among other things.
author | Holmes Futrell <hfutrell@umail.ucsb.edu> |
---|---|
date | Thu, 17 Jul 2008 23:07:58 +0000 |
parents | 91e601d9df8b |
children | 06d986e73eb0 |
comparison
equal
deleted
inserted
replaced
2356:5c27688b08cf | 2357:ad4a291c85ab |
---|---|
25 | 25 |
26 #include "SDL.h" | 26 #include "SDL.h" |
27 #include "SDL_sysvideo.h" | 27 #include "SDL_sysvideo.h" |
28 #include "SDL_blit.h" | 28 #include "SDL_blit.h" |
29 #include "SDL_pixels_c.h" | 29 #include "SDL_pixels_c.h" |
30 #include "SDL_renderer_gl.h" | 30 |
31 | |
32 #include "glrenderer/SDL_renderer_gl.h" | |
33 #include "glesrenderer/SDL_renderer_gles.h" | |
34 | |
31 #include "SDL_renderer_sw.h" | 35 #include "SDL_renderer_sw.h" |
32 #include "../events/SDL_sysevents.h" | 36 #include "../events/SDL_sysevents.h" |
33 #include "../events/SDL_events_c.h" | 37 #include "../events/SDL_events_c.h" |
38 | |
39 #if SDL_VIDEO_OPENGL_ES | |
40 #include "SDL_opengles.h" | |
41 #endif /* SDL_VIDEO_OPENGL_ES */ | |
34 | 42 |
35 #if SDL_VIDEO_OPENGL | 43 #if SDL_VIDEO_OPENGL |
36 #include "SDL_opengl.h" | 44 #include "SDL_opengl.h" |
37 | 45 |
38 /* On Windows, windows.h defines CreateWindow */ | 46 /* On Windows, windows.h defines CreateWindow */ |
100 #if SDL_VIDEO_DRIVER_RISCOS | 108 #if SDL_VIDEO_DRIVER_RISCOS |
101 &RISCOS_bootstrap, | 109 &RISCOS_bootstrap, |
102 #endif | 110 #endif |
103 #if SDL_VIDEO_DRIVER_OS2FS | 111 #if SDL_VIDEO_DRIVER_OS2FS |
104 &OS2FSLib_bootstrap, | 112 &OS2FSLib_bootstrap, |
113 #endif | |
114 #if SDL_VIDEO_DRIVER_UIKIT | |
115 &UIKIT_bootstrap, | |
105 #endif | 116 #endif |
106 #if SDL_VIDEO_DRIVER_DUMMY | 117 #if SDL_VIDEO_DRIVER_DUMMY |
107 &DUMMY_bootstrap, | 118 &DUMMY_bootstrap, |
108 #endif | 119 #endif |
109 NULL | 120 NULL |
241 _this->gl_config.accum_blue_size = 0; | 252 _this->gl_config.accum_blue_size = 0; |
242 _this->gl_config.accum_alpha_size = 0; | 253 _this->gl_config.accum_alpha_size = 0; |
243 _this->gl_config.stereo = 0; | 254 _this->gl_config.stereo = 0; |
244 _this->gl_config.multisamplebuffers = 0; | 255 _this->gl_config.multisamplebuffers = 0; |
245 _this->gl_config.multisamplesamples = 0; | 256 _this->gl_config.multisamplesamples = 0; |
257 _this->gl_config.retained_backing = 1; /* most systems have retained backing on the color buffers */ | |
246 _this->gl_config.accelerated = -1; /* not known, don't set */ | 258 _this->gl_config.accelerated = -1; /* not known, don't set */ |
247 | 259 |
248 /* Initialize the video subsystem */ | 260 /* Initialize the video subsystem */ |
249 if (_this->VideoInit(_this) < 0) { | 261 if (_this->VideoInit(_this) < 0) { |
250 SDL_VideoQuit(); | 262 SDL_VideoQuit(); |
260 | 272 |
261 /* The software renderer is always available */ | 273 /* The software renderer is always available */ |
262 for (i = 0; i < _this->num_displays; ++i) { | 274 for (i = 0; i < _this->num_displays; ++i) { |
263 #if SDL_VIDEO_RENDER_OGL | 275 #if SDL_VIDEO_RENDER_OGL |
264 SDL_AddRenderDriver(i, &GL_RenderDriver); | 276 SDL_AddRenderDriver(i, &GL_RenderDriver); |
277 #endif | |
278 | |
279 #if SDL_VIDEO_RENDER_OGL_ES | |
280 SDL_AddRenderDriver(i, &GL_ES_RenderDriver); | |
265 #endif | 281 #endif |
266 if (_this->displays[i].num_render_drivers > 0) { | 282 if (_this->displays[i].num_render_drivers > 0) { |
267 SDL_AddRenderDriver(i, &SW_RenderDriver); | 283 SDL_AddRenderDriver(i, &SW_RenderDriver); |
268 } | 284 } |
269 } | 285 } |
1408 return 0; | 1424 return 0; |
1409 } | 1425 } |
1410 | 1426 |
1411 if (index < 0) { | 1427 if (index < 0) { |
1412 const char *override = SDL_getenv("SDL_VIDEO_RENDERER"); | 1428 const char *override = SDL_getenv("SDL_VIDEO_RENDERER"); |
1413 int n = SDL_GetNumRenderDrivers(); | 1429 |
1430 int n = SDL_GetNumRenderDrivers(); | |
1431 | |
1414 for (index = 0; index < n; ++index) { | 1432 for (index = 0; index < n; ++index) { |
1415 SDL_RenderDriver *driver = | 1433 SDL_RenderDriver *driver = |
1416 &SDL_CurrentDisplay.render_drivers[index]; | 1434 &SDL_CurrentDisplay.render_drivers[index]; |
1417 | 1435 |
1418 if (override) { | 1436 if (override) { |
1441 SDL_DestroyRenderer(windowID); | 1459 SDL_DestroyRenderer(windowID); |
1442 | 1460 |
1443 /* Create a new renderer instance */ | 1461 /* Create a new renderer instance */ |
1444 window->renderer = SDL_CurrentDisplay.render_drivers[index] | 1462 window->renderer = SDL_CurrentDisplay.render_drivers[index] |
1445 .CreateRenderer(window, flags); | 1463 .CreateRenderer(window, flags); |
1464 | |
1446 SDL_SelectRenderer(window->id); | 1465 SDL_SelectRenderer(window->id); |
1447 | 1466 |
1448 return 0; | 1467 return 0; |
1449 } | 1468 } |
1450 | 1469 |
1544 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); | 1563 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); |
1545 return 0; | 1564 return 0; |
1546 } | 1565 } |
1547 fmt = surface->format; | 1566 fmt = surface->format; |
1548 | 1567 |
1549 if (format) { | 1568 if (format) { /* if we were passed in a format */ |
1550 if (!SDL_PixelFormatEnumToMasks | 1569 if (!SDL_PixelFormatEnumToMasks |
1551 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | 1570 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { |
1552 SDL_SetError("Unknown pixel format"); | 1571 SDL_SetError("Unknown pixel format"); |
1553 return 0; | 1572 return 0; |
1554 } | 1573 } |
1555 } else { | 1574 } else { |
1556 if (surface->format->Amask | 1575 if (surface->format->Amask |
1557 || !(surface->map->info.flags & | 1576 || !(surface->map->info.flags & |
1558 (SDL_COPY_COLORKEY | SDL_COPY_MASK | SDL_COPY_BLEND))) { | 1577 (SDL_COPY_COLORKEY | SDL_COPY_MASK | SDL_COPY_BLEND))) { |
1559 bpp = fmt->BitsPerPixel; | 1578 bpp = fmt->BitsPerPixel; |
1560 Rmask = fmt->Rmask; | 1579 Rmask = fmt->Rmask; |
1561 Gmask = fmt->Gmask; | 1580 Gmask = fmt->Gmask; |
1562 Bmask = fmt->Bmask; | 1581 Bmask = fmt->Bmask; |
1563 Amask = fmt->Amask; | 1582 Amask = fmt->Amask; |
1564 } else { | 1583 } else { |
1574 SDL_SetError("Unknown pixel format"); | 1593 SDL_SetError("Unknown pixel format"); |
1575 return 0; | 1594 return 0; |
1576 } | 1595 } |
1577 } | 1596 } |
1578 | 1597 |
1579 textureID = | 1598 textureID = SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w, |
1580 SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w, | |
1581 surface->h); | 1599 surface->h); |
1582 if (!textureID) { | 1600 if (!textureID) { |
1583 return 0; | 1601 return 0; |
1584 } | 1602 } |
1585 | 1603 |
1610 if (dst_fmt->palette) { | 1628 if (dst_fmt->palette) { |
1611 /* FIXME: Should we try to copy fmt->palette? */ | 1629 /* FIXME: Should we try to copy fmt->palette? */ |
1612 SDL_DitherColors(dst_fmt->palette->colors, | 1630 SDL_DitherColors(dst_fmt->palette->colors, |
1613 SDL_BITSPERPIXEL(format)); | 1631 SDL_BITSPERPIXEL(format)); |
1614 } | 1632 } |
1615 } | 1633 } |
1616 | 1634 dst = SDL_ConvertSurface(surface, dst_fmt, 0); |
1617 dst = SDL_ConvertSurface(surface, dst_fmt, 0); | |
1618 if (dst) { | 1635 if (dst) { |
1619 SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch); | 1636 SDL_UpdateTexture(textureID, NULL, dst->pixels, dst->pitch); |
1620 SDL_FreeSurface(dst); | 1637 SDL_FreeSurface(dst); |
1621 } | 1638 } |
1622 if (dst_fmt->palette) { | 1639 if (dst_fmt->palette) { |
1626 } | 1643 } |
1627 if (!dst) { | 1644 if (!dst) { |
1628 SDL_DestroyTexture(textureID); | 1645 SDL_DestroyTexture(textureID); |
1629 return 0; | 1646 return 0; |
1630 } | 1647 } |
1631 } | 1648 } |
1632 | 1649 |
1633 if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) { | 1650 if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) { |
1634 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, | 1651 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, |
1635 fmt->palette->ncolors); | 1652 fmt->palette->ncolors); |
1636 } | 1653 } |
1994 } | 2011 } |
1995 | 2012 |
1996 int | 2013 int |
1997 SDL_RenderFill(Uint8 r, Uint8 g, Uint8 b, Uint8 a, const SDL_Rect * rect) | 2014 SDL_RenderFill(Uint8 r, Uint8 g, Uint8 b, Uint8 a, const SDL_Rect * rect) |
1998 { | 2015 { |
2016 | |
1999 SDL_Renderer *renderer; | 2017 SDL_Renderer *renderer; |
2000 SDL_Window *window; | 2018 SDL_Window *window; |
2001 SDL_Rect real_rect; | 2019 SDL_Rect real_rect; |
2002 | 2020 |
2003 if (!_this) { | 2021 if (!_this) { |
2279 } | 2297 } |
2280 | 2298 |
2281 SDL_bool | 2299 SDL_bool |
2282 SDL_GL_ExtensionSupported(const char *extension) | 2300 SDL_GL_ExtensionSupported(const char *extension) |
2283 { | 2301 { |
2284 #if SDL_VIDEO_OPENGL | 2302 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES |
2285 const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); | 2303 |
2304 const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); | |
2286 const char *extensions; | 2305 const char *extensions; |
2287 const char *start; | 2306 const char *start; |
2288 const char *where, *terminator; | 2307 const char *where, *terminator; |
2289 | 2308 |
2290 /* Extension names should not have spaces. */ | 2309 /* Extension names should not have spaces. */ |
2335 } | 2354 } |
2336 | 2355 |
2337 int | 2356 int |
2338 SDL_GL_SetAttribute(SDL_GLattr attr, int value) | 2357 SDL_GL_SetAttribute(SDL_GLattr attr, int value) |
2339 { | 2358 { |
2340 #if SDL_VIDEO_OPENGL | 2359 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES |
2341 int retval; | 2360 int retval; |
2342 | 2361 |
2343 if (!_this) { | 2362 if (!_this) { |
2344 SDL_UninitializedVideo(); | 2363 SDL_UninitializedVideo(); |
2345 return -1; | 2364 return -1; |
2393 _this->gl_config.multisamplesamples = value; | 2412 _this->gl_config.multisamplesamples = value; |
2394 break; | 2413 break; |
2395 case SDL_GL_ACCELERATED_VISUAL: | 2414 case SDL_GL_ACCELERATED_VISUAL: |
2396 _this->gl_config.accelerated = value; | 2415 _this->gl_config.accelerated = value; |
2397 break; | 2416 break; |
2417 case SDL_GL_RETAINED_BACKING: | |
2418 _this->gl_config.retained_backing = value; | |
2419 break; | |
2398 default: | 2420 default: |
2399 SDL_SetError("Unknown OpenGL attribute"); | 2421 SDL_SetError("Unknown OpenGL attribute"); |
2400 retval = -1; | 2422 retval = -1; |
2401 break; | 2423 break; |
2402 } | 2424 } |
2408 } | 2430 } |
2409 | 2431 |
2410 int | 2432 int |
2411 SDL_GL_GetAttribute(SDL_GLattr attr, int *value) | 2433 SDL_GL_GetAttribute(SDL_GLattr attr, int *value) |
2412 { | 2434 { |
2413 #if SDL_VIDEO_OPENGL | 2435 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES |
2414 void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); | 2436 void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); |
2415 GLenum attrib = 0; | 2437 GLenum attrib = 0; |
2416 | 2438 |
2417 glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); | 2439 glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); |
2418 if (!glGetIntegervFunc) { | 2440 if (!glGetIntegervFunc) { |
2419 return -1; | 2441 return -1; |
2420 } | 2442 } |
2421 switch (attr) { | 2443 switch (attr) { |
2444 case SDL_GL_RETAINED_BACKING: | |
2445 *value = _this->gl_config.retained_backing; | |
2446 return 0; | |
2422 case SDL_GL_RED_SIZE: | 2447 case SDL_GL_RED_SIZE: |
2423 attrib = GL_RED_BITS; | 2448 attrib = GL_RED_BITS; |
2424 break; | 2449 break; |
2425 case SDL_GL_BLUE_SIZE: | 2450 case SDL_GL_BLUE_SIZE: |
2426 attrib = GL_BLUE_BITS; | 2451 attrib = GL_BLUE_BITS; |
2430 break; | 2455 break; |
2431 case SDL_GL_ALPHA_SIZE: | 2456 case SDL_GL_ALPHA_SIZE: |
2432 attrib = GL_ALPHA_BITS; | 2457 attrib = GL_ALPHA_BITS; |
2433 break; | 2458 break; |
2434 case SDL_GL_DOUBLEBUFFER: | 2459 case SDL_GL_DOUBLEBUFFER: |
2460 #ifndef SDL_VIDEO_OPENGL_ES | |
2435 attrib = GL_DOUBLEBUFFER; | 2461 attrib = GL_DOUBLEBUFFER; |
2436 break; | 2462 break; |
2463 #else | |
2464 /* I believe double buffering is the only option in OpenGL ES | |
2465 -- in any case, GL_DOUBLEBUFFER doesn't exist */ | |
2466 *value = 1; | |
2467 return 0; | |
2468 #endif | |
2437 case SDL_GL_DEPTH_SIZE: | 2469 case SDL_GL_DEPTH_SIZE: |
2438 attrib = GL_DEPTH_BITS; | 2470 attrib = GL_DEPTH_BITS; |
2439 break; | 2471 break; |
2440 case SDL_GL_STENCIL_SIZE: | 2472 case SDL_GL_STENCIL_SIZE: |
2441 attrib = GL_STENCIL_BITS; | 2473 attrib = GL_STENCIL_BITS; |
2442 break; | 2474 break; |
2475 #ifndef SDL_VIDEO_OPENGL_ES | |
2443 case SDL_GL_ACCUM_RED_SIZE: | 2476 case SDL_GL_ACCUM_RED_SIZE: |
2444 attrib = GL_ACCUM_RED_BITS; | 2477 attrib = GL_ACCUM_RED_BITS; |
2445 break; | 2478 break; |
2446 case SDL_GL_ACCUM_GREEN_SIZE: | 2479 case SDL_GL_ACCUM_GREEN_SIZE: |
2447 attrib = GL_ACCUM_GREEN_BITS; | 2480 attrib = GL_ACCUM_GREEN_BITS; |
2450 attrib = GL_ACCUM_BLUE_BITS; | 2483 attrib = GL_ACCUM_BLUE_BITS; |
2451 break; | 2484 break; |
2452 case SDL_GL_ACCUM_ALPHA_SIZE: | 2485 case SDL_GL_ACCUM_ALPHA_SIZE: |
2453 attrib = GL_ACCUM_ALPHA_BITS; | 2486 attrib = GL_ACCUM_ALPHA_BITS; |
2454 break; | 2487 break; |
2455 case SDL_GL_STEREO: | 2488 case SDL_GL_STEREO: |
2456 attrib = GL_STEREO; | 2489 attrib = GL_STEREO; |
2457 break; | 2490 break; |
2458 case SDL_GL_MULTISAMPLEBUFFERS: | 2491 #else |
2459 attrib = GL_SAMPLE_BUFFERS_ARB; | 2492 case SDL_GL_ACCUM_RED_SIZE: |
2460 break; | 2493 case SDL_GL_ACCUM_GREEN_SIZE: |
2461 case SDL_GL_MULTISAMPLESAMPLES: | 2494 case SDL_GL_ACCUM_BLUE_SIZE: |
2462 attrib = GL_SAMPLES_ARB; | 2495 case SDL_GL_ACCUM_ALPHA_SIZE: |
2463 break; | 2496 case SDL_GL_STEREO: |
2497 /* none of these are supported in OpenGL ES */ | |
2498 *value = 0; | |
2499 return 0; | |
2500 #endif | |
2501 case SDL_GL_MULTISAMPLEBUFFERS: | |
2502 #ifndef SDL_VIDEO_OPENGL_ES | |
2503 attrib = GL_SAMPLE_BUFFERS_ARB; | |
2504 #else | |
2505 attrib = GL_SAMPLE_BUFFERS; | |
2506 #endif | |
2507 break; | |
2508 case SDL_GL_MULTISAMPLESAMPLES: | |
2509 #ifndef SDL_VIDEO_OPENGL_ES | |
2510 attrib = GL_SAMPLES_ARB; | |
2511 #else | |
2512 attrib = GL_SAMPLES; | |
2513 #endif | |
2514 break; | |
2464 case SDL_GL_BUFFER_SIZE: | 2515 case SDL_GL_BUFFER_SIZE: |
2465 { | 2516 { |
2466 GLint bits = 0; | 2517 GLint bits = 0; |
2467 GLint component; | 2518 GLint component; |
2468 | 2519 |
2505 | 2556 |
2506 if (!window) { | 2557 if (!window) { |
2507 return NULL; | 2558 return NULL; |
2508 } | 2559 } |
2509 if (!(window->flags & SDL_WINDOW_OPENGL)) { | 2560 if (!(window->flags & SDL_WINDOW_OPENGL)) { |
2510 SDL_SetError("The specified window isn't an OpenGL window"); | |
2511 return NULL; | 2561 return NULL; |
2512 } | 2562 } |
2513 return _this->GL_CreateContext(_this, window); | 2563 return _this->GL_CreateContext(_this, window); |
2514 } | 2564 } |
2515 | 2565 |
2522 SDL_SetError("The specified window isn't an OpenGL window"); | 2572 SDL_SetError("The specified window isn't an OpenGL window"); |
2523 return -1; | 2573 return -1; |
2524 } | 2574 } |
2525 if (!context) { | 2575 if (!context) { |
2526 window = NULL; | 2576 window = NULL; |
2527 } | |
2528 if (window) { | |
2529 if (window->context == context) { | |
2530 return 0; | |
2531 } | |
2532 window->context = context; | |
2533 } | 2577 } |
2534 return _this->GL_MakeCurrent(_this, window, context); | 2578 return _this->GL_MakeCurrent(_this, window, context); |
2535 } | 2579 } |
2536 | 2580 |
2537 int | 2581 int |
2570 SDL_GL_SwapWindow(SDL_WindowID windowID) | 2614 SDL_GL_SwapWindow(SDL_WindowID windowID) |
2571 { | 2615 { |
2572 SDL_Window *window = SDL_GetWindowFromID(windowID); | 2616 SDL_Window *window = SDL_GetWindowFromID(windowID); |
2573 | 2617 |
2574 if (!window) { | 2618 if (!window) { |
2619 SDL_SetError("The specified window doesn't exist"); | |
2575 return; | 2620 return; |
2576 } | 2621 } |
2577 if (!(window->flags & SDL_WINDOW_OPENGL)) { | 2622 if (!(window->flags & SDL_WINDOW_OPENGL)) { |
2578 SDL_SetError("The specified window isn't an OpenGL window"); | 2623 SDL_SetError("The specified window isn't an OpenGL window"); |
2579 return; | 2624 return; |