From 130ee7e1d93efb6cc57470cf5b6d37568a6f0152 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 11 Jul 2017 20:38:47 -0300 Subject: [PATCH] Consolidated Image and Canvas dimension validation code. --HG-- branch : minor --- src/modules/graphics/Canvas.cpp | 38 +----------------- src/modules/graphics/Texture.cpp | 57 +++++++++++++++++++++++++++ src/modules/graphics/Texture.h | 2 + src/modules/graphics/opengl/Image.cpp | 16 +------- 4 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/modules/graphics/Canvas.cpp b/src/modules/graphics/Canvas.cpp index df5194ed2..a0626112f 100644 --- a/src/modules/graphics/Canvas.cpp +++ b/src/modules/graphics/Canvas.cpp @@ -97,43 +97,7 @@ Canvas::Canvas(const Settings &settings) throw love::Exception("%s textures are not supported on this system!", textypestr); } - int maxsize = 0; - switch (texType) - { - case TEXTURE_2D: - maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE]; - if (pixelWidth > maxsize) - throw TextureTooLargeException("width", pixelWidth); - else if (pixelHeight > maxsize) - throw TextureTooLargeException("height", pixelHeight); - break; - case TEXTURE_VOLUME: - maxsize = (int) caps.limits[Graphics::LIMIT_VOLUME_TEXTURE_SIZE]; - if (pixelWidth > maxsize) - throw TextureTooLargeException("width", pixelWidth); - else if (pixelHeight > maxsize) - throw TextureTooLargeException("height", pixelHeight); - else if (depth > maxsize) - throw TextureTooLargeException("depth", depth); - break; - case TEXTURE_2D_ARRAY: - maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE]; - if (pixelWidth > maxsize) - throw TextureTooLargeException("width", pixelWidth); - else if (pixelHeight > maxsize) - throw TextureTooLargeException("height", pixelHeight); - else if (layers > (int) caps.limits[Graphics::LIMIT_TEXTURE_LAYERS]) - throw TextureTooLargeException("array layer count", layers); - break; - case TEXTURE_CUBE: - if (pixelWidth != pixelHeight) - throw love::Exception("Cubemap textures must have equal width and height."); - else if (pixelWidth > (int) caps.limits[Graphics::LIMIT_CUBE_TEXTURE_SIZE]) - throw TextureTooLargeException("width", pixelWidth); - break; - default: - break; - } + validateDimensions(true); canvasCount++; } diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 80c951d32..57f6546fd 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -317,6 +317,63 @@ int Texture::getMipmapCount(int w, int h, int d) return (int) log2(std::max(std::max(w, h), d)) + 1; } +bool Texture::validateDimensions(bool throwException) const +{ + bool success = true; + + auto gfx = Module::getInstance(Module::M_GRAPHICS); + if (gfx == nullptr) + return false; + + const Graphics::Capabilities &caps = gfx->getCapabilities(); + + int max2Dsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE]; + int max3Dsize = (int) caps.limits[Graphics::LIMIT_VOLUME_TEXTURE_SIZE]; + int maxcubesize = (int) caps.limits[Graphics::LIMIT_CUBE_TEXTURE_SIZE]; + int maxlayers = (int) caps.limits[Graphics::LIMIT_TEXTURE_LAYERS]; + + int largestdim = 0; + const char *largestname = nullptr; + + if ((texType == TEXTURE_2D || texType == TEXTURE_2D_ARRAY) && (pixelWidth > max2Dsize || pixelHeight > max2Dsize)) + { + success = false; + largestdim = std::max(pixelWidth, pixelHeight); + largestname = pixelWidth > pixelHeight ? "pixel width" : "pixel height"; + } + else if (texType == TEXTURE_2D_ARRAY && layers > maxlayers) + { + success = false; + largestdim = layers; + largestname = "array layer count"; + } + else if (texType == TEXTURE_CUBE && (pixelWidth > maxcubesize || pixelWidth != pixelHeight)) + { + success = false; + largestdim = std::max(pixelWidth, pixelHeight); + largestname = pixelWidth > pixelHeight ? "pixel width" : "pixel height"; + + if (throwException && pixelWidth != pixelHeight) + throw love::Exception("Cubemap textures must have equal width and height."); + } + else if (texType == TEXTURE_VOLUME && (pixelWidth > max3Dsize || pixelHeight > max3Dsize || depth > max3Dsize)) + { + success = false; + largestdim = std::max(std::max(pixelWidth, pixelHeight), depth); + if (largestdim == pixelWidth) + largestname = "pixel width"; + else if (largestdim == pixelHeight) + largestname = "pixel height"; + else + largestname = "pixel depth"; + } + + if (throwException && largestname != nullptr) + throw love::Exception("Cannot create texture: %s of %d is too large for this system.", largestname, largestdim); + + return success; +} + bool Texture::getConstant(const char *in, TextureType &out) { return texTypes.find(in, out); diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 7d5b20180..9bf3dea43 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -174,6 +174,8 @@ protected: void initQuad(); void setGraphicsMemorySize(int64 size); + bool validateDimensions(bool throwException) const; + TextureType texType; PixelFormat format; diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 42c940e18..d04e4ff2b 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -221,22 +221,8 @@ bool Image::loadVolatile() glGenTextures(1, &texture); gl.bindTextureToUnit(this, 0, false); - bool loaddefault = false; - - int max2Dsize = gl.getMax2DTextureSize(); - int max3Dsize = gl.getMax3DTextureSize(); - - if ((texType == TEXTURE_2D || texType == TEXTURE_2D_ARRAY) && (pixelWidth > max2Dsize || pixelHeight > max2Dsize)) - loaddefault = true; - else if (texType == TEXTURE_2D_ARRAY && layers > gl.getMaxTextureLayers()) - loaddefault = true; - else if (texType == TEXTURE_CUBE && (pixelWidth > gl.getMaxCubeTextureSize() || pixelWidth != pixelHeight)) - loaddefault = true; - else if (texType == TEXTURE_VOLUME && (pixelWidth > max3Dsize || pixelHeight > max3Dsize || depth > max3Dsize)) - loaddefault = true; - // Use a default texture if the size is too big for the system. - if (loaddefault) + if (!validateDimensions(false)) { loadDefaultTexture(); return true;