Hans de Goede
Sat, 02 Sep 2006 07:38:15 -0700
Hi all, Well I've done some more testing and it turns out that although resizing the window as done in my latest patch is enough to get resizing to work properly with opengl, a call to SDL_SetVideoMode() really is needed for software rendering to things like recreate the underlying XImage, update the size and pitch of the SDL surface, etc. This version of the patch fixes things by calling SDL_SetVideoMode() from the resize function as needed, and includes code to take into account the fact(?) that the GLcontext gets recreated when SDL_SetVideoMode() is called for other OS. Since I'm not so sure that this is correct (the fact that the GLcontext gets recreated) otherwise people on macOS-X should have been seeing crashes, because SDL_SetVideoMode does get called under certain conditions already without the texture cache being cleared. So maybe people have been seeing crashes / problems when switching between Fullscreen and window for example, in which case this pathc is not only correct but needs to be expanded to also reinit the opengl stuff on fullscreen toggle. Or more likely my source for the GLcontext recreating is wrong. I'm currently thinking its the latter, but I'm not sure. I also don't know if the SDL_SetVideoMode call on user resize is needed by any other platforms. So I'll post a much cleaned up patch shortly which simply fixes things for Linux only, trying not todo any crystal ball stuff for any other platforms. Still I wanted to share this in case it is usefull for other platforms. Regards, Hans
diff -ur sdlmame0108u1.orig/src/sdl/drawsdl.c sdlmame0108u1/src/sdl/drawsdl.c
--- sdlmame0108u1.orig/src/sdl/drawsdl.c 2006-08-18 04:42:02.000000000 +0200
+++ sdlmame0108u1/src/sdl/drawsdl.c 2006-09-02 16:33:42.000000000 +0200
@@ -380,7 +380,8 @@
hofs = (window->wind_rect.right - sdl->blitwidth) / 2;
}
- surfptr += ((vofs * window->sdlsurf->pitch) + hofs*4);
+ surfptr += vofs * window->sdlsurf->pitch +
+ hofs * window->sdlsurf->format->BytesPerPixel;
// render to it
osd_lock_acquire(window->primlist->lock);
@@ -1331,6 +1332,22 @@
texture->texinfo.seqid = prim->texture.seqid;
}
}
+
+void drawsdl_destroy_all_textures(sdl_info *sdl)
+{
+ texture_info *next_texture, *texture = sdl->texlist;
+
+ while(texture)
+ {
+ next_texture = texture->next;
+ glDeleteTextures(1, &texture->texturename);
+ if (texture->data);
+ free(texture->data);
+ free(texture);
+ texture = next_texture;
+ }
+ sdl->texlist = NULL;
+}
#endif
//============================================================
diff -ur sdlmame0108u1.orig/src/sdl/window.c sdlmame0108u1/src/sdl/window.c
--- sdlmame0108u1.orig/src/sdl/window.c 2006-08-18 04:42:02.000000000 +0200
+++ sdlmame0108u1/src/sdl/window.c 2006-09-02 16:02:15.000000000 +0200
@@ -92,6 +93,7 @@
static void sdlwindow_exit(void);
static void sdlwindow_video_window_destroy(sdl_window_info *window);
static void draw_video_contents(sdl_window_info *window, UINT32 dc, int update);
+static void sdlwindow_init_ogl_context(void);
int complete_create(sdl_window_info *window);
static void set_starting_view(int index, sdl_window_info *window, const char *view);
@@ -160,11 +162,40 @@
//============================================================
void compute_blit_surface_size(sdl_window_info *window);
+void drawsdl_destroy_all_textures(sdl_info *sdl);
void sdlwindow_resize(INT32 width, INT32 height)
{
sdl_window_info *window = sdl_window_list;
-
+
+/* According to the SDL documentation this function should call
+ SDL_SetVideoMode() with the new width and height, see here:
+ http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fResizeEvent
+ However on MacOS-X and on windows this destroys and recreates the OpenGL
+ content (or so I've heared), requiring us to recreate all our cached
+ textures and redo the OpenGL context initialisation.
+
+ Under X11 not calling SDL_SetVideoMode() causes various problems both in
+ OpenGL and in software rendering mode. Under X11 however the OpenGL context
+ doesn't get destroyed, so we do not need to recreate our textures and
+ reinit our OpenGL context. Thus currently this gets skipped if we are under
+ X11. Perhaps the reinit of the OpenGL stuff or the SDL_SetVideoMode() can
+ be skipped under Windows / MacOS-X, this needs to be tested by people with
+ access to these platforms. According to this:
+ http://www.libsdl.org/pipermail/sdl/2006-June/075062.html
+ The SDL_SetVideoMode() is needed under windows, but can be hacked around.
+ If you test this under other platforms please test both the OpenGL and
+ software rendering modes. */
+#ifndef SDLMAME_LINUX
+ drawsdl_destroy_all_textures(window->dxdata);
+#endif
+ SDL_SetVideoMode(width, height, 0, SDL_SWSURFACE |
+ SDL_DOUBLEBUF | SDL_ANYFORMAT | window->extra_flags);
+
+#ifndef SDLMAME_LINUX
+ if (window->opengl)
+ sdlwindow_init_ogl_context();
+#endif
window->wind_rect.right = width;
window->wind_rect.bottom = height;
@@ -540,6 +571,17 @@
return 0;
}
+static void sdlwindow_init_ogl_context(void)
+{
+ // do some one-time OpenGL setup
+ glShadeModel(GL_SMOOTH);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClearDepth(1.0f);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+}
+
//============================================================
// complete_create
// (window thread)
@@ -637,13 +679,7 @@
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &sdl->texture_max_height);
printf("OpenGL: max texture size %d x %d\n", sdl->texture_max_width, sdl->texture_max_height);
- // do some one-time OpenGL setup
- glShadeModel(GL_SMOOTH);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClearDepth(1.0f);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ sdlwindow_init_ogl_context();
}
// maximum or minimize as appropriate