summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-07-22 23:15:58 +0200
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-07-23 08:21:41 +0200
commitf8252679bb7aa1ffb8d06d64cccba6e91c6d327b (patch)
tree4e4f0d8485f2e39e049e32304c37e3d073fa23ee
parent7a161c97f8925b4b2273ac88e5bcfe03b2fd3905 (diff)
downloadmana-f8252679bb7aa1ffb8d06d64cccba6e91c6d327b.tar.gz
mana-f8252679bb7aa1ffb8d06d64cccba6e91c6d327b.tar.bz2
mana-f8252679bb7aa1ffb8d06d64cccba6e91c6d327b.tar.xz
mana-f8252679bb7aa1ffb8d06d64cccba6e91c6d327b.zip
Avoid copying surfaces unnecessarily for upload to texture
When uploading an SDL surface to an OpenGL texture, it was always making a copy that had the desired size and pixel format. Now this copy is no longer being made when the existing surface already has the target size and pixel format. In fact most images are already in 32-bit RGBA format after loading them.
-rw-r--r--src/resources/image.cpp60
-rw-r--r--src/resources/image.h2
2 files changed, 36 insertions, 26 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index cf0d1483..b7e6c200 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -438,25 +438,22 @@ Image *Image::_SDLload(SDL_Surface *tmpImage)
}
#ifdef USE_OPENGL
-Image *Image::_GLload(SDL_Surface *tmpImage)
+Image *Image::_GLload(SDL_Surface *image)
{
// Flush current error flag.
glGetError();
- int width = tmpImage->w;
- int height = tmpImage->h;
+ int width = image->w;
+ int height = image->h;
int realWidth = powerOfTwo(width);
int realHeight = powerOfTwo(height);
if (realWidth < width || realHeight < height)
{
logger->log("Warning: image too large, cropping to %dx%d texture!",
- tmpImage->w, tmpImage->h);
+ realWidth, realHeight);
}
- // Make sure the alpha channel is not used, but copied to destination
- SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
-
// Determine 32-bit masks based on byte order
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
@@ -471,39 +468,52 @@ Image *Image::_GLload(SDL_Surface *tmpImage)
amask = 0xff000000;
#endif
- SDL_Surface *oldImage = tmpImage;
- tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
- 32, rmask, gmask, bmask, amask);
+ bool needsConversion = !(realWidth == width &&
+ realHeight == height &&
+ image->format->BytesPerPixel == 4 &&
+ image->format->Rmask == rmask &&
+ image->format->Gmask == gmask &&
+ image->format->Bmask == bmask &&
+ image->format->Amask == amask);
- if (!tmpImage)
+ if (needsConversion)
{
- logger->log("Error, image convert failed: out of memory");
- return NULL;
- }
+ SDL_Surface *oldImage = image;
+ image = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
+ 32, rmask, gmask, bmask, amask);
- SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);
+ if (!image)
+ {
+ logger->log("Error, image convert failed: out of memory");
+ return NULL;
+ }
+
+ // Make sure the alpha channel is not used, but copied to destination
+ SDL_SetAlpha(oldImage, 0, SDL_ALPHA_OPAQUE);
+ SDL_BlitSurface(oldImage, NULL, image, NULL);
+ }
GLuint texture;
glGenTextures(1, &texture);
OpenGLGraphics::bindTexture(mTextureType, texture);
- if (SDL_MUSTLOCK(tmpImage))
- SDL_LockSurface(tmpImage);
+ if (SDL_MUSTLOCK(image))
+ SDL_LockSurface(image);
- glTexImage2D(
- mTextureType, 0, GL_RGBA8,
- tmpImage->w, tmpImage->h,
- 0, GL_RGBA, GL_UNSIGNED_BYTE,
- tmpImage->pixels);
+ glTexImage2D(mTextureType, 0, GL_RGBA8,
+ image->w, image->h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ image->pixels);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- if (SDL_MUSTLOCK(tmpImage))
- SDL_UnlockSurface(tmpImage);
+ if (SDL_MUSTLOCK(image))
+ SDL_UnlockSurface(image);
- SDL_FreeSurface(tmpImage);
+ if (needsConversion)
+ SDL_FreeSurface(image);
GLenum error = glGetError();
if (error)
diff --git a/src/resources/image.h b/src/resources/image.h
index 33db7848..b1831ada 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -243,7 +243,7 @@ class Image : public Resource
*/
static int powerOfTwo(int input);
- static Image *_GLload(SDL_Surface *tmpImage);
+ static Image *_GLload(SDL_Surface *image);
GLuint mGLImage;
int mTexWidth, mTexHeight;