Mercurial > sdl-ios-xcode
comparison src/video/photon/SDL_photon.c @ 3193:64e4442676a6
Fixed problems with OpenGL ES window resizing.
author | Mike Gorchak <lestat@i.com.ua> |
---|---|
date | Thu, 11 Jun 2009 05:57:32 +0000 |
parents | 51750b7a966f |
children | dd105b317335 |
comparison
equal
deleted
inserted
replaced
3192:ec126b077b96 | 3193:64e4442676a6 |
---|---|
383 | 383 |
384 /* Query photon about graphics hardware caps and current video mode */ | 384 /* Query photon about graphics hardware caps and current video mode */ |
385 status = PgGetGraphicsHWCaps(&hwcaps); | 385 status = PgGetGraphicsHWCaps(&hwcaps); |
386 if (status != 0) { | 386 if (status != 0) { |
387 PhRect_t extent; | 387 PhRect_t extent; |
388 PdOffscreenContext_t *curctx; | 388 PdOffscreenContext_t* curctx; |
389 | 389 |
390 /* If error happens, this also could mean, that photon is working */ | 390 /* If error happens, this also could mean, that photon is working */ |
391 /* under custom (not listed by photon) video mode */ | 391 /* under custom (not listed by photon) video mode */ |
392 status = PhWindowQueryVisible(Ph_QUERY_GRAPHICS, 0, 0, &extent); | 392 status=PhWindowQueryVisible(Ph_QUERY_GRAPHICS, 0, 0, &extent); |
393 if (status != 0) { | 393 if (status != 0) { |
394 SDL_SetError("Photon: Can't get graphics driver region"); | 394 SDL_SetError("Photon: Can't get graphics driver region"); |
395 SDL_free(didata->cursor); | 395 SDL_free(didata->cursor); |
396 SDL_free(didata); | 396 SDL_free(didata); |
397 return -1; | 397 return -1; |
398 } | 398 } |
399 modeinfo.width = extent.lr.x + 1; | 399 modeinfo.width=extent.lr.x+1; |
400 modeinfo.height = extent.lr.y + 1; | 400 modeinfo.height=extent.lr.y+1; |
401 /* Hardcode 60Hz, as the base refresh rate frequency */ | 401 /* Hardcode 60Hz, as the base refresh rate frequency */ |
402 hwcaps.current_rrate = 60; | 402 hwcaps.current_rrate=60; |
403 /* Clear current video driver name, no way to get it somehow */ | 403 /* Clear current video driver name, no way to get it somehow */ |
404 hwcaps.chip_name[0] = 0x00; | 404 hwcaps.chip_name[0]=0x00; |
405 | 405 |
406 /* Create offscreen context from video memory, which is currently */ | 406 /* Create offscreen context from video memory, which is currently */ |
407 /* displayed on the screen */ | 407 /* displayed on the screen */ |
408 curctx = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY); | 408 curctx=PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY); |
409 if (curctx == NULL) { | 409 if (curctx==NULL) |
410 { | |
410 SDL_SetError("Photon: Can't get display area capabilities"); | 411 SDL_SetError("Photon: Can't get display area capabilities"); |
411 SDL_free(didata->cursor); | 412 SDL_free(didata->cursor); |
412 SDL_free(didata); | 413 SDL_free(didata); |
413 return -1; | 414 return -1; |
414 } | 415 } |
415 /* Retrieve current bpp */ | 416 /* Retrieve current bpp */ |
416 modeinfo.type = curctx->format; | 417 modeinfo.type=curctx->format; |
417 PhDCRelease(curctx); | 418 PhDCRelease(curctx); |
418 } else { | 419 } else { |
419 /* Get current video mode details */ | 420 /* Get current video mode details */ |
420 status = PgGetVideoModeInfo(hwcaps.current_video_mode, &modeinfo); | 421 status = PgGetVideoModeInfo(hwcaps.current_video_mode, &modeinfo); |
421 if (status != 0) { | 422 if (status != 0) { |
422 SDL_SetError | 423 SDL_SetError("Photon: Can't get current video mode information"); |
423 ("Photon: Can't get current video mode information"); | |
424 SDL_free(didata->cursor); | 424 SDL_free(didata->cursor); |
425 SDL_free(didata); | 425 SDL_free(didata); |
426 return -1; | 426 return -1; |
427 } | 427 } |
428 } | 428 } |
1241 } | 1241 } |
1242 wdata->window = NULL; | 1242 wdata->window = NULL; |
1243 | 1243 |
1244 #if defined(SDL_VIDEO_OPENGL_ES) | 1244 #if defined(SDL_VIDEO_OPENGL_ES) |
1245 if (phdata->gfinitialized == SDL_TRUE) { | 1245 if (phdata->gfinitialized == SDL_TRUE) { |
1246 /* Destroy photon handle to GF surface */ | |
1247 if (wdata->phsurface != NULL) { | |
1248 PhDCRelease(wdata->phsurface); | |
1249 wdata->phsurface=NULL; | |
1250 } | |
1251 | |
1246 /* Destroy OpenGL ES surface if it was created */ | 1252 /* Destroy OpenGL ES surface if it was created */ |
1247 if (wdata->gles_surface != EGL_NO_SURFACE) { | 1253 if (wdata->gles_surface != EGL_NO_SURFACE) { |
1248 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | 1254 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); |
1249 } | 1255 } |
1250 | 1256 |
1668 wdata->gles_context = EGL_NO_CONTEXT; | 1674 wdata->gles_context = EGL_NO_CONTEXT; |
1669 SDL_SetError("Photon: Can't create EGL pixmap surface"); | 1675 SDL_SetError("Photon: Can't create EGL pixmap surface"); |
1670 return NULL; | 1676 return NULL; |
1671 } | 1677 } |
1672 | 1678 |
1679 /* Store last used context and surface */ | |
1680 phdata->lgles_surface=wdata->gles_surface; | |
1681 phdata->lgles_context=wdata->gles_context; | |
1682 | |
1673 /* Make just created context current */ | 1683 /* Make just created context current */ |
1674 status = | 1684 status = |
1675 eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, | 1685 eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, |
1676 wdata->gles_surface, wdata->gles_context); | 1686 wdata->gles_surface, wdata->gles_context); |
1677 if (status != EGL_TRUE) { | 1687 if (status != EGL_TRUE) { |
1688 /* Reset last used context and surface */ | |
1689 phdata->lgles_surface=EGL_NO_SURFACE; | |
1690 phdata->lgles_context=EGL_NO_CONTEXT; | |
1691 | |
1678 /* Destroy OpenGL ES surface */ | 1692 /* Destroy OpenGL ES surface */ |
1679 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | 1693 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); |
1694 wdata->gles_surface=EGL_NO_SURFACE; | |
1680 gf_surface_free(wdata->gfsurface); | 1695 gf_surface_free(wdata->gfsurface); |
1681 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | 1696 eglDestroyContext(phdata->egldisplay, wdata->gles_context); |
1682 wdata->gles_context = EGL_NO_CONTEXT; | 1697 wdata->gles_context = EGL_NO_CONTEXT; |
1683 SDL_SetError("Photon: Can't set OpenGL ES context on creation"); | 1698 SDL_SetError("Photon: Can't set OpenGL ES context on creation"); |
1684 return NULL; | 1699 return NULL; |
1737 /* Set target device as default for Pd and Pg functions */ | 1752 /* Set target device as default for Pd and Pg functions */ |
1738 status = PdSetTargetDevice(NULL, phdata->rid[didata->device_id]); | 1753 status = PdSetTargetDevice(NULL, phdata->rid[didata->device_id]); |
1739 if (status != 0) { | 1754 if (status != 0) { |
1740 /* Destroy OpenGL ES surface */ | 1755 /* Destroy OpenGL ES surface */ |
1741 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | 1756 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); |
1757 wdata->gles_surface=EGL_NO_SURFACE; | |
1742 gf_surface_free(wdata->gfsurface); | 1758 gf_surface_free(wdata->gfsurface); |
1743 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | 1759 eglDestroyContext(phdata->egldisplay, wdata->gles_context); |
1744 wdata->gles_context = EGL_NO_CONTEXT; | 1760 wdata->gles_context = EGL_NO_CONTEXT; |
1745 SDL_SetError("Photon: Can't set default target device\n"); | 1761 SDL_SetError("Photon: Can't set default target device\n"); |
1746 return NULL; | 1762 return NULL; |
1750 | 1766 |
1751 wdata->phsurface = PdCreateOffscreenContextGF(wdata->gfsurface); | 1767 wdata->phsurface = PdCreateOffscreenContextGF(wdata->gfsurface); |
1752 if (wdata->phsurface == NULL) { | 1768 if (wdata->phsurface == NULL) { |
1753 /* Destroy OpenGL ES surface */ | 1769 /* Destroy OpenGL ES surface */ |
1754 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | 1770 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); |
1771 wdata->gles_surface=EGL_NO_SURFACE; | |
1755 gf_surface_free(wdata->gfsurface); | 1772 gf_surface_free(wdata->gfsurface); |
1756 eglDestroyContext(phdata->egldisplay, wdata->gles_context); | 1773 eglDestroyContext(phdata->egldisplay, wdata->gles_context); |
1757 wdata->gles_context = EGL_NO_CONTEXT; | 1774 wdata->gles_context = EGL_NO_CONTEXT; |
1758 SDL_SetError("Photon: Can't bind GF surface to Photon\n"); | 1775 SDL_SetError("Photon: Can't bind GF surface to Photon\n"); |
1759 return NULL; | 1776 return NULL; |
1780 ("Photon: GF initialization failed, no OpenGL ES support"); | 1797 ("Photon: GF initialization failed, no OpenGL ES support"); |
1781 return -1; | 1798 return -1; |
1782 } | 1799 } |
1783 | 1800 |
1784 if ((window == NULL) && (context == NULL)) { | 1801 if ((window == NULL) && (context == NULL)) { |
1802 /* Reset last used context and surface */ | |
1803 phdata->lgles_surface=EGL_NO_SURFACE; | |
1804 phdata->lgles_context=EGL_NO_CONTEXT; | |
1805 | |
1806 /* Unset current context */ | |
1785 status = | 1807 status = |
1786 eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, | 1808 eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, |
1787 EGL_NO_CONTEXT); | 1809 EGL_NO_CONTEXT); |
1788 if (status != EGL_TRUE) { | 1810 if (status != EGL_TRUE) { |
1789 /* Failed to set current GL ES context */ | 1811 /* Failed to set current GL ES context */ |
1790 SDL_SetError("Photon: Can't set OpenGL ES context"); | 1812 SDL_SetError("Photon: Can't empty current OpenGL ES context"); |
1791 return -1; | 1813 return -1; |
1792 } | 1814 } |
1793 } else { | 1815 } else { |
1794 wdata = (SDL_WindowData *) window->driverdata; | 1816 wdata = (SDL_WindowData *) window->driverdata; |
1795 if (wdata->gles_surface == EGL_NO_SURFACE) { | 1817 if (wdata->gles_surface == EGL_NO_SURFACE) { |
1805 if (wdata->gles_context != context) { | 1827 if (wdata->gles_context != context) { |
1806 SDL_SetError | 1828 SDL_SetError |
1807 ("Photon: OpenGL ES context is not belong to this window"); | 1829 ("Photon: OpenGL ES context is not belong to this window"); |
1808 return -1; | 1830 return -1; |
1809 } | 1831 } |
1832 | |
1833 /* Store last set surface and context */ | |
1834 phdata->lgles_surface=wdata->gles_surface; | |
1835 phdata->lgles_context=wdata->gles_context; | |
1836 | |
1837 /* Set new current context */ | |
1810 status = | 1838 status = |
1811 eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, | 1839 eglMakeCurrent(phdata->egldisplay, wdata->gles_surface, |
1812 wdata->gles_surface, wdata->gles_context); | 1840 wdata->gles_surface, wdata->gles_context); |
1813 if (status != EGL_TRUE) { | 1841 if (status != EGL_TRUE) { |
1842 /* Reset last used context and surface */ | |
1843 phdata->lgles_surface=EGL_NO_SURFACE; | |
1844 phdata->lgles_context=EGL_NO_CONTEXT; | |
1814 /* Failed to set current GL ES context */ | 1845 /* Failed to set current GL ES context */ |
1815 SDL_SetError("Photon: Can't set OpenGL ES context"); | 1846 SDL_SetError("Photon: Can't set OpenGL ES context"); |
1816 return -1; | 1847 return -1; |
1817 } | 1848 } |
1818 } | 1849 } |
1892 SDL_SetError | 1923 SDL_SetError |
1893 ("Photon: GF initialization failed, no OpenGL ES support"); | 1924 ("Photon: GF initialization failed, no OpenGL ES support"); |
1894 return; | 1925 return; |
1895 } | 1926 } |
1896 | 1927 |
1928 if (wdata->phsurface==NULL) { | |
1929 SDL_SetError | |
1930 ("Photon: Photon OpenGL ES surface is not initialized"); | |
1931 return; | |
1932 } | |
1933 | |
1897 /* Many applications do not uses glFinish(), so we call it for them */ | 1934 /* Many applications do not uses glFinish(), so we call it for them */ |
1898 glFinish(); | 1935 glFinish(); |
1899 | 1936 |
1900 /* Wait until OpenGL ES rendering is completed */ | 1937 /* Wait until OpenGL ES rendering is completed */ |
1901 eglWaitGL(); | 1938 eglWaitGL(); |
1943 } | 1980 } |
1944 | 1981 |
1945 /* Check if OpenGL ES connection has been initialized */ | 1982 /* Check if OpenGL ES connection has been initialized */ |
1946 if (phdata->egldisplay != EGL_NO_DISPLAY) { | 1983 if (phdata->egldisplay != EGL_NO_DISPLAY) { |
1947 if (context != EGL_NO_CONTEXT) { | 1984 if (context != EGL_NO_CONTEXT) { |
1985 /* Check if we are destroying current active context */ | |
1986 if (phdata->lgles_context==context) { | |
1987 /* Release current context */ | |
1988 eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
1989 phdata->lgles_context=EGL_NO_CONTEXT; | |
1990 phdata->lgles_surface=EGL_NO_SURFACE; | |
1991 } | |
1948 status = eglDestroyContext(phdata->egldisplay, context); | 1992 status = eglDestroyContext(phdata->egldisplay, context); |
1949 if (status != EGL_TRUE) { | 1993 if (status != EGL_TRUE) { |
1950 /* Error during OpenGL ES context destroying */ | 1994 /* Error during OpenGL ES context destroying */ |
1951 SDL_SetError("Photon: OpenGL ES context destroy error"); | 1995 SDL_SetError("Photon: OpenGL ES context destroy error"); |
1952 return; | 1996 return; |
1956 | 2000 |
1957 return; | 2001 return; |
1958 #else | 2002 #else |
1959 SDL_SetError("Photon: OpenGL ES support is not compiled in"); | 2003 SDL_SetError("Photon: OpenGL ES support is not compiled in"); |
1960 return; | 2004 return; |
2005 #endif /* SDL_VIDEO_OPENGL_ES */ | |
2006 } | |
2007 | |
2008 /* Helper function, which re-creates surface, not an API */ | |
2009 int photon_gl_recreatesurface(_THIS, SDL_Window * window, uint32_t width, uint32_t height) | |
2010 { | |
2011 #if defined(SDL_VIDEO_OPENGL_ES) | |
2012 SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; | |
2013 SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; | |
2014 SDL_DisplayData *didata = | |
2015 (SDL_DisplayData *) SDL_CurrentDisplay.driverdata; | |
2016 SDL_bool makecurrent=SDL_FALSE; | |
2017 int32_t gfstatus; | |
2018 | |
2019 /* Check if context has been initialized */ | |
2020 if (wdata->gles_context == EGL_NO_CONTEXT) { | |
2021 /* If no, abort surface re-creating */ | |
2022 return -1; | |
2023 } | |
2024 | |
2025 /* Check if last used surface the same as one which must be re-created */ | |
2026 if (phdata->lgles_surface == wdata->gles_surface) { | |
2027 makecurrent=SDL_TRUE; | |
2028 /* Flush all current drawings */ | |
2029 glFinish(); | |
2030 /* Wait until OpenGL ES rendering is completed */ | |
2031 eglWaitGL(); | |
2032 /* Release current context */ | |
2033 eglMakeCurrent(phdata->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
2034 phdata->lgles_surface=EGL_NO_SURFACE; | |
2035 } | |
2036 | |
2037 /* Check if we need to destroy previous surface */ | |
2038 if (wdata->gles_surface != EGL_NO_SURFACE) { | |
2039 /* Destroy photon handle to GF surface */ | |
2040 if (wdata->phsurface != NULL) { | |
2041 PhDCRelease(wdata->phsurface); | |
2042 wdata->phsurface=NULL; | |
2043 } | |
2044 | |
2045 /* Destroy previous surface */ | |
2046 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
2047 | |
2048 /* Set surface to uninitialized */ | |
2049 wdata->gles_surface = EGL_NO_SURFACE; | |
2050 | |
2051 if (wdata->gfsurface!=NULL) { | |
2052 gf_surface_free(wdata->gfsurface); | |
2053 wdata->gfsurface=NULL; | |
2054 } | |
2055 } | |
2056 | |
2057 /* Create new GF surface */ | |
2058 gfstatus = | |
2059 gf_surface_create(&wdata->gfsurface, phdata->gfdev, width, | |
2060 height, | |
2061 qnxgf_sdl_to_gf_pixelformat(didata->current_mode. | |
2062 format), NULL, | |
2063 GF_SURFACE_CREATE_2D_ACCESSIBLE | | |
2064 GF_SURFACE_CREATE_3D_ACCESSIBLE | | |
2065 GF_SURFACE_CREATE_SHAREABLE); | |
2066 if (gfstatus != GF_ERR_OK) { | |
2067 SDL_SetError("Photon: Can't create GF 3D surface (%08X)", gfstatus); | |
2068 return -1; | |
2069 } | |
2070 | |
2071 /* Create new pixmap 3D target surface */ | |
2072 wdata->gles_surface = | |
2073 eglCreatePixmapSurface(phdata->egldisplay, | |
2074 wdata->gles_configs[wdata->gles_config], | |
2075 wdata->gfsurface, NULL); | |
2076 if (wdata->gles_surface == EGL_NO_SURFACE) { | |
2077 gf_surface_free(wdata->gfsurface); | |
2078 wdata->gfsurface=NULL; | |
2079 SDL_SetError("Photon: Can't create EGL pixmap surface"); | |
2080 return -1; | |
2081 } | |
2082 | |
2083 wdata->phsurface = PdCreateOffscreenContextGF(wdata->gfsurface); | |
2084 if (wdata->phsurface == NULL) { | |
2085 /* Destroy OpenGL ES surface */ | |
2086 eglDestroySurface(phdata->egldisplay, wdata->gles_surface); | |
2087 wdata->gles_surface=EGL_NO_SURFACE; | |
2088 gf_surface_free(wdata->gfsurface); | |
2089 wdata->gfsurface=NULL; | |
2090 SDL_SetError("Photon: Can't bind GF surface to Photon\n"); | |
2091 return -1; | |
2092 } | |
2093 | |
2094 /* Check if we need to set this surface and context as current */ | |
2095 if (makecurrent == SDL_TRUE) { | |
2096 return photon_gl_makecurrent(_this, window, wdata->gles_context); | |
2097 } else { | |
2098 return 0; | |
2099 } | |
2100 #else | |
2101 /* Do nothing, if OpenGL ES support is not compiled in */ | |
2102 return 0; | |
1961 #endif /* SDL_VIDEO_OPENGL_ES */ | 2103 #endif /* SDL_VIDEO_OPENGL_ES */ |
1962 } | 2104 } |
1963 | 2105 |
1964 /*****************************************************************************/ | 2106 /*****************************************************************************/ |
1965 /* SDL Event handling function */ | 2107 /* SDL Event handling function */ |
2517 /* Set new window position after resize */ | 2659 /* Set new window position after resize */ |
2518 SDL_SendWindowEvent(window->id, | 2660 SDL_SendWindowEvent(window->id, |
2519 SDL_WINDOWEVENT_MOVED, | 2661 SDL_WINDOWEVENT_MOVED, |
2520 wmevent->pos.x, | 2662 wmevent->pos.x, |
2521 wmevent->pos.y); | 2663 wmevent->pos.y); |
2664 | |
2665 /* Check if this window uses OpenGL ES */ | |
2666 if (wdata->uses_gles == SDL_TRUE) { | |
2667 /* If so, recreate surface with new dimensions */ | |
2668 photon_gl_recreatesurface(_this, window, wmevent->size.w, wmevent->size.h); | |
2669 } | |
2670 | |
2522 /* Set new window size after resize */ | 2671 /* Set new window size after resize */ |
2523 SDL_SendWindowEvent(window->id, | 2672 SDL_SendWindowEvent(window->id, |
2524 SDL_WINDOWEVENT_RESIZED, | 2673 SDL_WINDOWEVENT_RESIZED, |
2525 wmevent->size.w, | 2674 wmevent->size.w, |
2526 wmevent->size.h); | 2675 wmevent->size.h); |