Mercurial > sdl-ios-xcode
diff src/video/qnxgf/SDL_qnxgf.c @ 3109:7b3a09fb9c8b
Support for HID devices (mice and keyboards only for now) has been added
author | Mike Gorchak <lestat@i.com.ua> |
---|---|
date | Tue, 28 Apr 2009 04:33:30 +0000 |
parents | 82e60908fab1 |
children | b17f1ae7ad66 |
line wrap: on
line diff
--- a/src/video/qnxgf/SDL_qnxgf.c Tue Apr 28 04:30:52 2009 +0000 +++ b/src/video/qnxgf/SDL_qnxgf.c Tue Apr 28 04:33:30 2009 +0000 @@ -37,6 +37,8 @@ #include "SDL_qnxgf.h" #include "SDL_gf_render.h" #include "SDL_gf_pixelfmt.h" +#include "SDL_gf_opengles.h" +#include "SDL_gf_input.h" /******************************************************************************/ /* SDL Generic video modes, which could provide GF */ @@ -248,6 +250,13 @@ return NULL; } + if (gfdata->gfdev_info.description==NULL) + { + gf_dev_detach(gfdata->gfdev); + SDL_SetError("GF: Failed to initialize graphics driver"); + return NULL; + } + /* Setup amount of available displays and current display */ device->num_displays=0; device->current_display=0; @@ -312,6 +321,10 @@ uint32_t it; uint32_t jt; char* override; + int32_t status; + + /* By default GF uses buffer swap on vsync */ + gfdata->swapinterval=1; /* Add each detected output to SDL */ for (it=0; it<gfdata->gfdev_info.ndisplays; it++) @@ -319,7 +332,6 @@ SDL_VideoDisplay display; SDL_DisplayMode current_mode; SDL_DisplayData* didata; - int status; didata=(SDL_DisplayData*)SDL_calloc(1, sizeof(SDL_DisplayData)); if (didata==NULL) @@ -329,6 +341,36 @@ return -1; } + /* Set default cursor settings, maximum 128x128 cursor */ + didata->cursor_visible=SDL_FALSE; + didata->cursor.type=GF_CURSOR_BITMAP; + didata->cursor.hotspot.x=0; + didata->cursor.hotspot.y=0; + didata->cursor.cursor.bitmap.w=SDL_VIDEO_GF_MAX_CURSOR_SIZE; + didata->cursor.cursor.bitmap.h=SDL_VIDEO_GF_MAX_CURSOR_SIZE; + didata->cursor.cursor.bitmap.stride=(didata->cursor.cursor.bitmap.w+7)/ + (sizeof(uint8_t)*8); + didata->cursor.cursor.bitmap.color0=0x00000000; + didata->cursor.cursor.bitmap.color1=0x00000000; + didata->cursor.cursor.bitmap.image0=SDL_calloc(sizeof(uint8_t), (didata->cursor.cursor.bitmap.w+7)* + didata->cursor.cursor.bitmap.h/(sizeof(uint8_t)*8)); + if (didata->cursor.cursor.bitmap.image0==NULL) + { + SDL_free(didata); + SDL_OutOfMemory(); + return -1; + } + didata->cursor.cursor.bitmap.image1=SDL_calloc(sizeof(uint8_t), (didata->cursor.cursor.bitmap.w+7)* + didata->cursor.cursor.bitmap.h/(sizeof(uint8_t)*8)); + if (didata->cursor.cursor.bitmap.image1==NULL) + { + SDL_OutOfMemory(); + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free(didata); + return -1; + } + + /* Query current display settings */ status=gf_display_query(gfdata->gfdev, it, &didata->display_info); if (status==GF_ERR_OK) { @@ -342,6 +384,8 @@ else { /* video initialization problem */ + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free((void*)didata->cursor.cursor.bitmap.image1); SDL_free(didata); SDL_SetError("GF: Display query failed"); return -1; @@ -352,6 +396,8 @@ if (status!=GF_ERR_OK) { /* video initialization problem */ + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free((void*)didata->cursor.cursor.bitmap.image1); SDL_free(didata); SDL_SetError("GF: Couldn't attach to display"); return -1; @@ -364,18 +410,64 @@ status=gf_layer_attach(&didata->layer, didata->display, didata->display_info.main_layer_index, 0); if (status!=GF_ERR_OK) { + /* Failed to attach to main layer */ + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free((void*)didata->cursor.cursor.bitmap.image1); + SDL_free(didata); SDL_SetError("GF: Couldn't attach to main layer, it could be busy"); + return -1; + } + + /* Mark main display layer is attached */ + didata->layer_attached=SDL_TRUE; + + /* Set layer source and destination viewport */ + gf_layer_set_src_viewport(didata->layer, 0, 0, current_mode.w-1, current_mode.h-1); + gf_layer_set_dst_viewport(didata->layer, 0, 0, current_mode.w-1, current_mode.h-1); - /* Failed to attach to main layer */ + /* Create main visible on display surface */ + status=gf_surface_create_layer(&didata->surface[0], &didata->layer, + 1, 0, current_mode.w, current_mode.h, + qnxgf_sdl_to_gf_pixelformat(current_mode.format), + NULL, GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE | + GF_SURFACE_CREATE_SHAREABLE); + if (status!=GF_ERR_OK) + { + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free((void*)didata->cursor.cursor.bitmap.image1); + SDL_free(didata); + SDL_SetError("GF: Can't create main layer surface at init (%d)\n", status); + return -1; + } + + /* Set just created surface as main visible on the layer */ +// gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1); + + /* Update layer parameters */ + status=gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE); + if (status!=GF_ERR_OK) + { + /* Free allocated surface */ + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + + /* Disable and detach from layer */ + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + SDL_free((void*)didata->cursor.cursor.bitmap.image1); + SDL_free(didata); + SDL_SetError("GF: Can't update layer parameters\n"); return -1; } /* Enable layer in case if hardware supports layer enable/disable */ gf_layer_enable(didata->layer); - /* Mark main display layer is attached */ - didata->layer_attached=SDL_TRUE; - /* Copy device name for each display */ SDL_strlcpy(didata->description, gfdata->gfdev_info.description, SDL_VIDEO_GF_DEVICENAME_MAX-1); @@ -395,9 +487,9 @@ /* Initialize display structure */ SDL_zero(display); - display.desktop_mode = current_mode; - display.current_mode = current_mode; - display.driverdata = didata; + display.desktop_mode=current_mode; + display.current_mode=current_mode; + display.driverdata=didata; didata->current_mode=current_mode; SDL_AddVideoDisplay(&display); @@ -411,11 +503,26 @@ didata->custom_refresh=0; } } + + /* Get all display modes for this display */ + _this->current_display=it; + qnxgf_getdisplaymodes(_this); } + /* Restore default display */ + _this->current_display=0; + /* Add GF renderer to SDL */ gf_addrenderdriver(_this); + /* Add GF input devices */ + status=gf_addinputdevices(_this); + if (status!=0) + { + /* SDL error is set by gf_addinputdevices() function */ + return -1; + } + /* video has been initialized successfully */ return 1; } @@ -425,11 +532,58 @@ SDL_DisplayData* didata; uint32_t it; - /* SDL will restore our desktop mode on exit */ + /* Delete GF input devices */ + gf_delinputdevices(_this); + + /* SDL will restore old desktop mode on exit */ for(it=0; it<_this->num_displays; it++) { didata=_this->displays[it].driverdata; + /* Free cursor image */ + if (didata->cursor.cursor.bitmap.image0!=NULL) + { + SDL_free((void*)didata->cursor.cursor.bitmap.image0); + } + if (didata->cursor.cursor.bitmap.image1!=NULL) + { + SDL_free((void*)didata->cursor.cursor.bitmap.image1); + } + + /* Free main surface */ + if (didata->surface[0]!=NULL) + { + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + } + + /* Free back surface */ + if (didata->surface[1]!=NULL) + { + gf_surface_free(didata->surface[1]); + didata->surface[1]=NULL; + } + + /* Free second back surface */ + if (didata->surface[2]!=NULL) + { + gf_surface_free(didata->surface[2]); + didata->surface[2]=NULL; + } + + /* Detach layer before quit */ + if (didata->layer_attached==SDL_TRUE) + { + /* Disable layer if hardware supports this */ + gf_layer_disable(didata->layer); + + /* Detach from layer, free it for others */ + gf_layer_detach(didata->layer); + + /* Mark it as detached */ + didata->layer_attached=SDL_FALSE; + } + /* Detach from selected display */ gf_display_detach(didata->display); } @@ -523,7 +677,7 @@ { SDL_DisplayData* didata=(SDL_DisplayData*)SDL_CurrentDisplay.driverdata; uint32_t refresh_rate=0; - int result; + int status; /* Current display dimensions and bpp are no more valid */ didata->current_mode.format=SDL_PIXELFORMAT_UNKNOWN; @@ -617,6 +771,27 @@ } } + /* Free main surface */ + if (didata->surface[0]!=NULL) + { + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + } + + /* Free back surface */ + if (didata->surface[1]!=NULL) + { + gf_surface_free(didata->surface[1]); + didata->surface[1]=NULL; + } + + /* Free second back surface */ + if (didata->surface[2]!=NULL) + { + gf_surface_free(didata->surface[2]); + didata->surface[2]=NULL; + } + /* Detach layer before switch to new graphics mode */ if (didata->layer_attached==SDL_TRUE) { @@ -631,9 +806,9 @@ } /* Set new display video mode */ - result=gf_display_set_mode(didata->display, mode->w, mode->h, refresh_rate, + status=gf_display_set_mode(didata->display, mode->w, mode->h, refresh_rate, qnxgf_sdl_to_gf_pixelformat(mode->format), 0); - if (result!=GF_ERR_OK) + if (status!=GF_ERR_OK) { /* Display mode/resolution switch has been failed */ SDL_SetError("GF: Mode is not supported by graphics driver"); @@ -646,8 +821,8 @@ } /* Attach to main display layer */ - result=gf_layer_attach(&didata->layer, didata->display, didata->display_info.main_layer_index, 0); - if (result!=GF_ERR_OK) + status=gf_layer_attach(&didata->layer, didata->display, didata->display_info.main_layer_index, 0); + if (status!=GF_ERR_OK) { SDL_SetError("GF: Couldn't attach to main layer, it could be busy"); @@ -655,12 +830,56 @@ return -1; } + /* Mark main display layer is attached */ + didata->layer_attached=SDL_TRUE; + + /* Set layer source and destination viewport */ + gf_layer_set_src_viewport(didata->layer, 0, 0, mode->w-1, mode->h-1); + gf_layer_set_dst_viewport(didata->layer, 0, 0, mode->w-1, mode->h-1); + + /* Create main visible on display surface */ + status=gf_surface_create_layer(&didata->surface[0], &didata->layer, 1, 0, + mode->w, mode->h, qnxgf_sdl_to_gf_pixelformat(mode->format), + NULL, GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE | + GF_SURFACE_CREATE_SHAREABLE); + if (status!=GF_ERR_OK) + { + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_SetError("GF: Can't create main layer surface at modeswitch (%d)\n", status); + return -1; + } + + /* Set just created surface as main visible on the layer */ + gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1); + + /* Update layer parameters */ + status=gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE); + if (status!=GF_ERR_OK) + { + /* Free main surface */ + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + + /* Detach layer */ + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_SetError("GF: Can't update layer parameters\n"); + return -1; + } + + /* Restore cursor if it was visible */ + if (didata->cursor_visible==SDL_TRUE) + { + gf_cursor_set(didata->display, 0, &didata->cursor); + gf_cursor_enable(didata->display, 0); + } + /* Enable layer in case if hardware supports layer enable/disable */ gf_layer_enable(didata->layer); - /* Mark main display layer is attached */ - didata->layer_attached=SDL_TRUE; - return 0; } @@ -766,7 +985,7 @@ } } - /* Setup our own window decorations, which are depend on fullscreen mode */ + /* Setup our own window decorations and states, which are depend on fullscreen mode */ window->flags|=SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS; @@ -823,6 +1042,13 @@ #endif /* SDL_VIDEO_OPENGL_ES */ } + /* Enable mouse event collecting */ + hiddi_enable_mouse(); + + /* By default last created window got a input focus */ + SDL_SetKeyboardFocus(0, window->id); + SDL_SetMouseFocus(0, window->id); + /* Window has been successfully created */ return 0; } @@ -896,9 +1122,9 @@ if (wdata->target_created==SDL_TRUE) { gf_3d_target_free(wdata->target); + wdata->target_created==SDL_FALSE; } - gfdata->egl_refcount--; if (gfdata->egl_refcount==0) { @@ -1001,8 +1227,22 @@ } } + /* Add emulated OpenGL ES 1.1 functions */ + if (SDL_strcmp(proc, "glTexParameteri")==0) + { + return glTexParameteri; + } + if (SDL_strcmp(proc, "glTexParameteriv")==0) + { + return glTexParameteriv; + } + if (SDL_strcmp(proc, "glColor4ub")==0) + { + return glColor4ub; + } + /* Failed to get GL ES function address pointer */ - SDL_SetError("GF: Cannot locate given function name"); + SDL_SetError("GF: Cannot locate OpenGL ES function name"); return NULL; #else SDL_SetError("GF: OpenGL ES support is not compiled in"); @@ -1036,6 +1276,125 @@ EGLint configs; uint32_t surfaces; uint32_t attr_pos; + EGLint attr_value; + EGLint cit; + + /* Choose buffeingr scheme */ + if (!_this->gl_config.double_buffer) + { + surfaces=1; + } + else + { + surfaces=2; + } + + /* Free main surface */ + if (didata->surface[0]!=NULL) + { + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + } + + /* Free back surface */ + if (didata->surface[1]!=NULL) + { + gf_surface_free(didata->surface[1]); + didata->surface[1]=NULL; + } + + /* Free second back surface */ + if (didata->surface[2]!=NULL) + { + gf_surface_free(didata->surface[2]); + didata->surface[2]=NULL; + } + + /* Detach layer before switch to new graphics mode */ + if (didata->layer_attached==SDL_TRUE) + { + /* Disable layer if hardware supports this */ + gf_layer_disable(didata->layer); + + /* Detach from layer, free it for others */ + gf_layer_detach(didata->layer); + + /* Mark it as detached */ + didata->layer_attached=SDL_FALSE; + } + + /* Attach to main display layer */ + gfstatus=gf_layer_attach(&didata->layer, didata->display, didata->display_info.main_layer_index, 0); + if (gfstatus!=GF_ERR_OK) + { + SDL_SetError("GF: Couldn't attach to main layer, it could be busy"); + + /* Failed to attach to main displayable layer */ + return NULL; + } + + /* Mark main display layer is attached */ + didata->layer_attached=SDL_TRUE; + + /* Set layer source and destination viewport */ + gf_layer_set_src_viewport(didata->layer, 0, 0, didata->current_mode.w-1, didata->current_mode.h-1); + gf_layer_set_dst_viewport(didata->layer, 0, 0, didata->current_mode.w-1, didata->current_mode.h-1); + + /* Create main visible on display surface */ + gfstatus=gf_surface_create_layer(&didata->surface[0], &didata->layer, 1, 0, + didata->current_mode.w, didata->current_mode.h, qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format), + NULL, GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE | + GF_SURFACE_CREATE_SHAREABLE); + if (gfstatus!=GF_ERR_OK) + { + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_SetError("GF: Can't create main layer surface at glctx (%d)\n", gfstatus); + return NULL; + } + + /* Set just created surface as main visible on the layer */ +// gf_layer_set_surfaces(didata->layer, &didata->surface[0], 1); + + if (surfaces>1) + { + /* Create back display surface */ + gfstatus=gf_surface_create_layer(&didata->surface[1], &didata->layer, 1, 0, + didata->current_mode.w, didata->current_mode.h, qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format), + NULL, GF_SURFACE_CREATE_2D_ACCESSIBLE | GF_SURFACE_CREATE_3D_ACCESSIBLE | + GF_SURFACE_CREATE_SHAREABLE); + if (gfstatus!=GF_ERR_OK) + { + gf_surface_free(didata->surface[0]); + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_SetError("GF: Can't create main layer surface at glctx (%d)\n", gfstatus); + return NULL; + } + } + + /* Update layer parameters */ + gfstatus=gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE); + if (gfstatus!=GF_ERR_OK) + { + /* Free main and back surfaces */ + gf_surface_free(didata->surface[1]); + didata->surface[1]=NULL; + gf_surface_free(didata->surface[0]); + didata->surface[0]=NULL; + + /* Detach layer */ + gf_layer_disable(didata->layer); + gf_layer_detach(didata->layer); + didata->layer_attached=SDL_FALSE; + SDL_SetError("GF: Can't update layer parameters\n"); + return NULL; + } + + /* Enable layer in case if hardware supports layer enable/disable */ + gf_layer_enable(didata->layer); /* Prepare attributes list to pass them to OpenGL ES */ attr_pos=0; @@ -1069,19 +1428,6 @@ wdata->gles_attributes[attr_pos++]=_this->gl_config.buffer_size; } - /* OpenGL ES 1.0 uses double buffer by default, so if application */ - /* do not requested double buffering, switch to single buffer */ - if (!_this->gl_config.double_buffer) - { - wdata->gles_attributes[attr_pos++]=EGL_SINGLE_BUFFER; - wdata->gles_attributes[attr_pos++]=EGL_TRUE; - surfaces=1; - } - else - { - surfaces=2; - } - /* Set number of samples in multisampling */ if (_this->gl_config.multisamplesamples) { @@ -1100,15 +1446,161 @@ wdata->gles_attributes[attr_pos]=EGL_NONE; /* Request first suitable framebuffer configuration */ - status=eglChooseConfig(gfdata->egldisplay, wdata->gles_attributes, &wdata->gles_config, 1, &configs); + status=eglChooseConfig(gfdata->egldisplay, wdata->gles_attributes, + wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs); if (status!=EGL_TRUE) { SDL_SetError("GF: Can't find closest configuration for OpenGL ES"); return NULL; } + /* Check if nothing has been found, try "don't care" settings */ + if (configs==0) + { + int32_t it; + int32_t jt; + GLint depthbits[4]={32, 24, 16, EGL_DONT_CARE}; + + for (it=0; it<4; it++) + { + for (jt=16; jt>=0; jt--) + { + /* Don't care about color buffer bits, use what exist */ + /* Replace previous data set with EGL_DONT_CARE */ + attr_pos=0; + wdata->gles_attributes[attr_pos++]=EGL_NATIVE_VISUAL_ID; + wdata->gles_attributes[attr_pos++]=qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format); + wdata->gles_attributes[attr_pos++]=EGL_RED_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos++]=EGL_GREEN_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos++]=EGL_BLUE_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos++]=EGL_ALPHA_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos++]=EGL_BUFFER_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + + /* Try to find requested or smallest depth */ + if (_this->gl_config.depth_size) + { + wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE; + wdata->gles_attributes[attr_pos++]=depthbits[it]; + } + else + { + wdata->gles_attributes[attr_pos++]=EGL_DEPTH_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + } + + if (_this->gl_config.stencil_size) + { + wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; + wdata->gles_attributes[attr_pos++]=jt; + } + else + { + wdata->gles_attributes[attr_pos++]=EGL_STENCIL_SIZE; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + + /* exit from stencil loop */ + jt=0; + } + + /* Don't care about antialiasing */ + wdata->gles_attributes[attr_pos++]=EGL_SAMPLES; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos++]=EGL_SAMPLE_BUFFERS; + wdata->gles_attributes[attr_pos++]=EGL_DONT_CARE; + wdata->gles_attributes[attr_pos]=EGL_NONE; + + /* Request first suitable framebuffer configuration */ + status=eglChooseConfig(gfdata->egldisplay, wdata->gles_attributes, + wdata->gles_configs, SDL_VIDEO_GF_OPENGLES_CONFS, &configs); + if (status!=EGL_TRUE) + { + SDL_SetError("Photon: Can't find closest configuration for OpenGL ES"); + return NULL; + } + if (configs!=0) + { + break; + } + } + if (configs!=0) + { + break; + } + } + + /* No available configs */ + if (configs==0) + { + SDL_SetError("Photon: Can't find any configuration for OpenGL ES"); + return NULL; + } + } + + /* Initialize config index */ + wdata->gles_config=0; + + /* Now check each configuration to find out the best */ + for (cit=0; cit<configs; cit++) + { + uint32_t stencil_found; + uint32_t depth_found; + + stencil_found=0; + depth_found=0; + + if (_this->gl_config.stencil_size) + { + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[cit], EGL_STENCIL_SIZE, &attr_value); + if (status==EGL_TRUE) + { + if (attr_value!=0) + { + stencil_found=1; + } + } + } + else + { + stencil_found=1; + } + + if (_this->gl_config.depth_size) + { + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[cit], EGL_DEPTH_SIZE, &attr_value); + if (status==EGL_TRUE) + { + if (attr_value!=0) + { + depth_found=1; + } + } + } + else + { + depth_found=1; + } + + /* Exit from loop if found appropriate configuration */ + if ((depth_found!=0) && (stencil_found!=0)) + { + break; + } + } + + /* If best could not be found, use first */ + if (cit==configs) + { + cit=0; + } + wdata->gles_config=cit; + /* Create OpenGL ES context */ - wdata->gles_context=eglCreateContext(gfdata->egldisplay, wdata->gles_config, EGL_NO_CONTEXT, NULL); + wdata->gles_context=eglCreateContext(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_NO_CONTEXT, NULL); if (wdata->gles_context==EGL_NO_CONTEXT) { SDL_SetError("GF: OpenGL ES context creation has been failed"); @@ -1119,13 +1611,13 @@ if (wdata->target_created==SDL_TRUE) { gf_3d_target_free(wdata->target); + wdata->target_created==SDL_FALSE; } /* Create surface(s) target for OpenGL ES */ - gfstatus=gf_3d_target_create(&wdata->target, didata->layer, NULL, + gfstatus=gf_3d_target_create(&wdata->target, didata->layer, &didata->surface[0], surfaces, didata->current_mode.w, didata->current_mode.h, qnxgf_sdl_to_gf_pixelformat(didata->current_mode.format)); - if (gfstatus!=GF_ERR_OK) { /* Destroy just created context */ @@ -1143,7 +1635,7 @@ } /* Create target rendering surface on whole screen */ - wdata->gles_surface=eglCreateWindowSurface(gfdata->egldisplay, wdata->gles_config, wdata->target, NULL); + wdata->gles_surface=eglCreateWindowSurface(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], wdata->target, NULL); if (wdata->gles_surface==EGL_NO_SURFACE) { /* Destroy 3d target */ @@ -1192,7 +1684,39 @@ /* Always clear stereo enable, since OpenGL ES do not supports stereo */ _this->gl_config.stereo=0; - /* Failed to create GL ES context */ + /* Get back samples and samplebuffers configurations. Rest framebuffer */ + /* parameters could be obtained through the OpenGL ES API */ + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLES, &attr_value); + if (status==EGL_TRUE) + { + _this->gl_config.multisamplesamples=attr_value; + } + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_SAMPLE_BUFFERS, &attr_value); + if (status==EGL_TRUE) + { + _this->gl_config.multisamplebuffers=attr_value; + } + + /* Get back stencil and depth buffer sizes */ + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_DEPTH_SIZE, &attr_value); + if (status==EGL_TRUE) + { + _this->gl_config.depth_size=attr_value; + } + status=eglGetConfigAttrib(gfdata->egldisplay, wdata->gles_configs[wdata->gles_config], EGL_STENCIL_SIZE, &attr_value); + if (status==EGL_TRUE) + { + _this->gl_config.stencil_size=attr_value; + } + + /* Restore cursor if it was visible */ + if (didata->cursor_visible==SDL_TRUE) + { + gf_cursor_set(didata->display, 0, &didata->cursor); + gf_cursor_enable(didata->display, 0); + } + + /* GL ES context was successfully created */ return wdata->gles_context; #else SDL_SetError("GF: OpenGL ES support is not compiled in"); @@ -1283,6 +1807,10 @@ SDL_VideoData* gfdata=(SDL_VideoData*)_this->driverdata; SDL_WindowData* wdata=(SDL_WindowData*)window->driverdata; + /* Finish all drawings */ + glFinish(); + + /* Swap buffers */ eglSwapBuffers(gfdata->egldisplay, wdata->gles_surface); #else SDL_SetError("GF: OpenGL ES support is not compiled in");