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);