# HG changeset patch # User Sam Lantinga # Date 1153602177 0 # Node ID 69217fdd2c0abdf8bb5f55af54de6bb729d41a9c # Parent d4572b97b08fbef63856a13ab4802b8e94c4928e If the OpenGL renderer is selected for a non-OpenGL window, recreate the window with OpenGL enabled. Added OpenGL renderer error checking. Use fast-path texture formats in the OpenGL renderer. diff -r d4572b97b08f -r 69217fdd2c0a src/SDL_compat.c --- a/src/SDL_compat.c Sat Jul 22 19:51:48 2006 +0000 +++ b/src/SDL_compat.c Sat Jul 22 21:02:57 2006 +0000 @@ -469,7 +469,8 @@ height); if (!SDL_VideoTexture) { SDL_VideoTexture = - SDL_CreateTexture(0, SDL_TextureAccess_Local, width, height); + SDL_CreateTexture(SDL_PixelFormat_RGB888, SDL_TextureAccess_Local, + width, height); } if (!SDL_VideoTexture) { return NULL; diff -r d4572b97b08f -r 69217fdd2c0a src/video/SDL_renderer_gl.c --- a/src/video/SDL_renderer_gl.c Sat Jul 22 19:51:48 2006 +0000 +++ b/src/video/SDL_renderer_gl.c Sat Jul 22 21:02:57 2006 +0000 @@ -72,7 +72,7 @@ SDL_TextureBlendMode_Mod), (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast | SDL_TextureScaleMode_Slow), - 18, + 16, { SDL_PixelFormat_Index1LSB, SDL_PixelFormat_Index1MSB, @@ -88,10 +88,8 @@ SDL_PixelFormat_RGB888, SDL_PixelFormat_BGR888, SDL_PixelFormat_ARGB8888, - SDL_PixelFormat_RGBA8888, SDL_PixelFormat_ABGR8888, - SDL_PixelFormat_BGRA8888, - SDL_PixelFormat_ARGB2101010}, /* FIXME: YUV texture support */ + SDL_PixelFormat_ARGB2101010}, 0, 0} }; @@ -115,6 +113,43 @@ } GL_TextureData; +static void +GL_SetError(const char *prefix, GLenum result) +{ + const char *error; + + switch (result) { + case GL_NO_ERROR: + error = "GL_NO_ERROR"; + break; + case GL_INVALID_ENUM: + error = "GL_INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "GL_INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "GL_INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "GL_STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "GL_STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "GL_OUT_OF_MEMORY"; + break; + case GL_TABLE_TOO_LARGE: + error = "GL_TABLE_TOO_LARGE"; + break; + default: + error = "UNKNOWN"; + break; + } + SDL_SetError("%s: %s", prefix, error); +} + void GL_AddRenderDriver(_THIS) { @@ -130,9 +165,10 @@ GL_RenderData *data; if (!(window->flags & SDL_WINDOW_OPENGL)) { - SDL_SetError - ("The OpenGL renderer can only be used on OpenGL windows"); - return NULL; + window->flags |= SDL_WINDOW_OPENGL; + if (SDL_RecreateWindow(window) < 0) { + return NULL; + } } renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); @@ -239,6 +275,7 @@ GLint internalFormat; GLenum format, type; int texture_w, texture_h; + GLenum result; switch (texture->format) { case SDL_PixelFormat_Index1LSB: @@ -289,8 +326,8 @@ break; case SDL_PixelFormat_RGB888: internalFormat = GL_RGB8; - format = GL_RGB; - type = GL_UNSIGNED_INT_8_8_8_8; + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; break; case SDL_PixelFormat_BGR24: internalFormat = GL_RGB8; @@ -299,28 +336,18 @@ break; case SDL_PixelFormat_BGR888: internalFormat = GL_RGB8; - format = GL_BGR; - type = GL_UNSIGNED_INT_8_8_8_8; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; break; case SDL_PixelFormat_ARGB8888: internalFormat = GL_RGBA8; format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - case SDL_PixelFormat_RGBA8888: - internalFormat = GL_RGBA8; - format = GL_RGBA; - type = GL_UNSIGNED_INT_8_8_8_8; + type = GL_UNSIGNED_BYTE; break; case SDL_PixelFormat_ABGR8888: internalFormat = GL_RGBA8; format = GL_RGBA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - case SDL_PixelFormat_BGRA8888: - internalFormat = GL_RGBA8; - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8; + type = GL_UNSIGNED_BYTE; break; case SDL_PixelFormat_ARGB2101010: internalFormat = GL_RGB10_A2; @@ -340,7 +367,7 @@ texture->driverdata = data; - /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */ + glGetError(); glGenTextures(1, &data->texture); #ifdef USE_GL_TEXTURE_RECTANGLE data->type = GL_TEXTURE_RECTANGLE_ARB; @@ -360,7 +387,11 @@ glBindTexture(data->type, data->texture); glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, format, type, NULL); - + result = glGetError(); + if (result != GL_NO_ERROR) { + GL_SetError("glTexImage2D()", result); + return -1; + } return 0; } @@ -383,19 +414,36 @@ return 0; } +static void +SetupTextureUpdate(SDL_Texture * texture, int pitch) +{ + if (texture->format == SDL_PixelFormat_Index1LSB) { + glPixelStorei(GL_UNPACK_LSB_FIRST, 1); + } else if (texture->format == SDL_PixelFormat_Index1MSB) { + glPixelStorei(GL_UNPACK_LSB_FIRST, 0); + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, + pitch / SDL_BYTESPERPIXEL(texture->format)); +} + static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GLenum result; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, - pitch / SDL_BYTESPERPIXEL(texture->format)); + glGetError(); + SetupTextureUpdate(texture, pitch); glBindTexture(data->type, data->texture); glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h, data->format, data->formattype, pixels); - /* FIXME: check for errors */ + result = glGetError(); + if (result != GL_NO_ERROR) { + GL_SetError("glTexSubImage2D()", result); + return -1; + } return 0; } @@ -478,9 +526,7 @@ int bpp = SDL_BYTESPERPIXEL(texture->format); int pitch = texturedata->pitch; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, - pitch / SDL_BYTESPERPIXEL(texture->format)); + SetupTextureUpdate(texture, pitch); glBindTexture(texturedata->type, texturedata->texture); for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { SDL_Rect *rect = &dirty->rect; diff -r d4572b97b08f -r 69217fdd2c0a src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h Sat Jul 22 19:51:48 2006 +0000 +++ b/src/video/SDL_sysvideo.h Sat Jul 22 21:02:57 2006 +0000 @@ -397,6 +397,7 @@ extern void SDL_AddRenderDriver(int displayIndex, const SDL_RenderDriver * driver); +extern int SDL_RecreateWindow(SDL_Window * window); extern SDL_Window *SDL_GetWindowFromID(SDL_WindowID windowID); extern SDL_VideoDisplay *SDL_GetDisplayFromWindow(SDL_Window * window); diff -r d4572b97b08f -r 69217fdd2c0a src/video/SDL_video.c --- a/src/video/SDL_video.c Sat Jul 22 19:51:48 2006 +0000 +++ b/src/video/SDL_video.c Sat Jul 22 21:02:57 2006 +0000 @@ -833,6 +833,20 @@ return window.id; } +int +SDL_RecreateWindow(SDL_Window * window) +{ + if ((window->flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { + window->flags &= ~SDL_WINDOW_OPENGL; + SDL_SetError("No OpenGL support in video driver"); + return -1; + } + if (_this->DestroyWindow) { + _this->DestroyWindow(_this, window); + } + return _this->CreateWindow(_this, window); +} + SDL_Window * SDL_GetWindowFromID(SDL_WindowID windowID) { @@ -1259,6 +1273,7 @@ if (window->title) { SDL_free(window->title); } + SDL_free(window); if (j != display->num_windows - 1) { SDL_memcpy(&display->windows[i], &display->windows[i + 1], @@ -1421,6 +1436,9 @@ texture->renderer = renderer; if (renderer->CreateTexture(renderer, texture) < 0) { + if (renderer->DestroyTexture) { + renderer->DestroyTexture(renderer, texture); + } SDL_free(texture); return 0; } diff -r d4572b97b08f -r 69217fdd2c0a src/video/win32/SDL_d3drender.c --- a/src/video/win32/SDL_d3drender.c Sat Jul 22 19:51:48 2006 +0000 +++ b/src/video/win32/SDL_d3drender.c Sat Jul 22 21:02:57 2006 +0000 @@ -396,7 +396,6 @@ PixelFormatToD3DFMT(texture->format), pool, &data->texture, NULL); if (FAILED(result)) { - SDL_free(data); D3D_SetError("CreateTexture()", result); return -1; } diff -r d4572b97b08f -r 69217fdd2c0a src/video/win32/SDL_gdirender.c --- a/src/video/win32/SDL_gdirender.c Sat Jul 22 19:51:48 2006 +0000 +++ b/src/video/win32/SDL_gdirender.c Sat Jul 22 21:02:57 2006 +0000 @@ -249,7 +249,6 @@ if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { data->yuv = SDL_SW_CreateYUVTexture(texture); if (!data->yuv) { - GDI_DestroyTexture(renderer, texture); return -1; } data->format = display->current_mode.format; @@ -266,7 +265,6 @@ bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); if (!bmi) { - GDI_DestroyTexture(renderer, texture); SDL_OutOfMemory(); return -1; } @@ -291,7 +289,6 @@ ncolors * sizeof(PALETTEENTRY)); if (!palette) { SDL_free(bmi); - GDI_DestroyTexture(renderer, texture); SDL_OutOfMemory(); return -1; } @@ -327,7 +324,6 @@ data->pixels = NULL; } if (!data->hbm) { - GDI_DestroyTexture(renderer, texture); WIN_SetError("Couldn't create bitmap"); return -1; } diff -r d4572b97b08f -r 69217fdd2c0a test/common.c --- a/test/common.c Sat Jul 22 19:51:48 2006 +0000 +++ b/test/common.c Sat Jul 22 21:02:57 2006 +0000 @@ -55,9 +55,6 @@ if (!argv[index]) { return -1; } - if (SDL_strcasecmp(argv[index], "opengl") == 0) { - state->window_flags |= SDL_WINDOW_OPENGL; - } state->renderdriver = argv[index]; return 2; }