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-08-05 17:15:56 +0200
commit1fe16bdda5fa0d7112f4568e7bcd892d01c197b9 (patch)
tree2c5200f374a43ceb01f55b3954697b1cd7b5f9bc
parent020ddd64a48229a8d5e9dcccf4fe1fe71c840450 (diff)
downloadMana-1fe16bdda5fa0d7112f4568e7bcd892d01c197b9.tar.gz
Mana-1fe16bdda5fa0d7112f4568e7bcd892d01c197b9.tar.bz2
Mana-1fe16bdda5fa0d7112f4568e7bcd892d01c197b9.tar.xz
Mana-1fe16bdda5fa0d7112f4568e7bcd892d01c197b9.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. Reviewed-by: Erik Schilling
-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;