Browse Source

Move more backend-agnostic code out of the love.graphics opengl implementation files.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
16f5557131

+ 128 - 0
src/modules/graphics/Image.cpp

@@ -39,6 +39,8 @@ Image::Image(const Slices &data, const Settings &settings, bool validatedata)
 	, data(data)
 	, mipmapsType(settings.mipmaps ? MIPMAPS_GENERATED : MIPMAPS_NONE)
 	, sRGB(isGammaCorrect() && !settings.linear)
+	, usingDefaultTexture(false)
+	, textureMemorySize(0)
 {
 	if (validatedata && data.validate() == MIPMAPS_DATA)
 		mipmapsType = MIPMAPS_DATA;
@@ -46,11 +48,137 @@ Image::Image(const Slices &data, const Settings &settings, bool validatedata)
 	++imageCount;
 }
 
+Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
+	: Image(Slices(textype), settings, false)
+{
+	if (isPixelFormatCompressed(format))
+		throw love::Exception("This constructor is only supported for non-compressed pixel formats.");
+
+	if (textype == TEXTURE_2D_ARRAY)
+		layers = slices;
+	else if (textype == TEXTURE_VOLUME)
+		depth = slices;
+
+	init(format, width, height, settings);
+}
+
+Image::Image(const Slices &slices, const Settings &settings)
+	: Image(slices, settings, true)
+{
+	if (texType == TEXTURE_2D_ARRAY)
+		this->layers = data.getSliceCount();
+	else if (texType == TEXTURE_VOLUME)
+		this->depth = data.getSliceCount();
+
+	love::image::ImageDataBase *slice = data.get(0, 0);
+	init(slice->getFormat(), slice->getWidth(), slice->getHeight(), settings);
+}
+
 Image::~Image()
 {
 	--imageCount;
 }
 
+void Image::init(PixelFormat fmt, int w, int h, const Settings &settings)
+{
+	pixelWidth = w;
+	pixelHeight = h;
+
+	width  = (int) (pixelWidth / settings.pixeldensity + 0.5);
+	height = (int) (pixelHeight / settings.pixeldensity + 0.5);
+
+	mipmapCount = mipmapsType == MIPMAPS_NONE ? 1 : getMipmapCount(w, h);
+	format = fmt;
+
+	if (isCompressed() && mipmapsType == MIPMAPS_GENERATED)
+		mipmapsType = MIPMAPS_NONE;
+
+	if (getMipmapCount() > 1)
+		filter.mipmap = defaultMipmapFilter;
+	
+	initQuad();
+}
+
+void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice)
+{
+	love::image::ImageData *id = dynamic_cast<love::image::ImageData *>(d);
+
+	love::thread::EmptyLock lock;
+	if (id != nullptr)
+		lock.setLock(id->getMutex());
+
+	Rect rect = {0, 0, d->getWidth(), d->getHeight()};
+	uploadByteData(d->getFormat(), d->getData(), d->getSize(), rect, level, slice);
+}
+
+void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps)
+{
+	// No effect if the texture hasn't been created yet.
+	if (getHandle() == 0 || usingDefaultTexture)
+		return;
+
+	if (d->getFormat() != getPixelFormat())
+		throw love::Exception("Pixel formats must match.");
+
+	if (mipmap < 0 || (mipmapsType != MIPMAPS_DATA && mipmap > 0) || mipmap >= getMipmapCount())
+		throw love::Exception("Invalid image mipmap index.");
+
+	if (slice < 0 || (texType == TEXTURE_CUBE && slice >= 6)
+		|| (texType == TEXTURE_VOLUME && slice >= std::max(getDepth() >> mipmap, 1))
+		|| (texType == TEXTURE_2D_ARRAY && slice >= getLayerCount()))
+	{
+		throw love::Exception("Invalid image slice index.");
+	}
+
+	love::image::ImageDataBase *oldd = data.get(slice, mipmap);
+
+	if (oldd == nullptr)
+		throw love::Exception("Image does not store ImageData!");
+
+	int w = d->getWidth();
+	int h = d->getHeight();
+
+	if (w != oldd->getWidth() || h != oldd->getHeight())
+		throw love::Exception("Dimensions must match the texture's dimensions for the specified mipmap level.");
+
+	Graphics::flushStreamDrawsGlobal();
+
+	d->retain();
+	oldd->release();
+
+	data.set(slice, mipmap, d);
+
+	uploadImageData(d, mipmap, slice);
+
+	if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
+		generateMipmaps();
+}
+
+void Image::replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps)
+{
+	Graphics::flushStreamDrawsGlobal();
+
+	uploadByteData(format, data, size, rect, mipmap, slice);
+
+	if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
+		generateMipmaps();
+}
+
+bool Image::isCompressed() const
+{
+	return isPixelFormatCompressed(format);
+}
+
+bool Image::isFormatLinear() const
+{
+	return isGammaCorrect() && !sRGB;
+}
+
+Image::MipmapsType Image::getMipmapsType() const
+{
+	return mipmapsType;
+}
+
 Image::Slices::Slices(TextureType textype)
 	: textureType(textype)
 {

+ 25 - 8
src/modules/graphics/Image.h

@@ -85,19 +85,24 @@ public:
 
 	virtual ~Image();
 
-	virtual void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps) = 0;
-	virtual void replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps) = 0;
+	void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps);
+	void replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps);
 
-	virtual bool isFormatLinear() const = 0;
-	virtual bool isCompressed() const = 0;
-
-	virtual MipmapsType getMipmapsType() const = 0;
+	bool isFormatLinear() const;
+	bool isCompressed() const;
+	MipmapsType getMipmapsType() const;
 
 	static int imageCount;
 
 protected:
 
-	Image(const Slices &data, const Settings &settings, bool validatedata);
+	Image(const Slices &data, const Settings &settings);
+	Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings);
+
+	void uploadImageData(love::image::ImageDataBase *d, int level, int slice);
+	virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, const Rect &rect, int level, int slice) = 0;
+
+	virtual void generateMipmaps() = 0;
 
 	// The settings used to initialize this Image.
 	Settings settings;
@@ -106,7 +111,19 @@ protected:
 
 	MipmapsType mipmapsType;
 	bool sRGB;
-	
+
+	// True if the image wasn't able to be properly created and it had to fall
+	// back to a default texture.
+	bool usingDefaultTexture;
+
+	size_t textureMemorySize;
+
+private:
+
+	Image(const Slices &data, const Settings &settings, bool validatedata);
+
+	void init(PixelFormat fmt, int w, int h, const Settings &settings);
+
 }; // Image
 
 } // graphics

+ 4 - 5
src/modules/graphics/opengl/Canvas.cpp

@@ -454,11 +454,10 @@ ptrdiff_t Canvas::getHandle() const
 
 love::image::ImageData *Canvas::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &r)
 {
-	love::image::ImageData *imagedata = love::graphics::Canvas::newImageData(module, slice, mipmap, r);
-	PixelFormat dataformat = imagedata->getFormat();
+	love::image::ImageData *data = love::graphics::Canvas::newImageData(module, slice, mipmap, r);
 
 	bool isSRGB = false;
-	OpenGL::TextureFormat fmt = gl.convertPixelFormat(dataformat, false, isSRGB);
+	OpenGL::TextureFormat fmt = gl.convertPixelFormat(data->getFormat(), false, isSRGB);
 
 	GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 	gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, getFBO());
@@ -470,14 +469,14 @@ love::image::ImageData *Canvas::newImageData(love::image::Image *module, int sli
 		gl.framebufferTexture(GL_COLOR_ATTACHMENT0, texType, texture, mipmap, layer, face);
 	}
 
-	glReadPixels(r.x, r.y, r.w, r.h, fmt.externalformat, fmt.type, imagedata->getData());
+	glReadPixels(r.x, r.y, r.w, r.h, fmt.externalformat, fmt.type, data->getData());
 
 	if (slice > 0 || mipmap > 0)
 		gl.framebufferTexture(GL_COLOR_ATTACHMENT0, texType, texture, 0, 0, 0);
 
 	gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
 
-	return imagedata;
+	return data;
 }
 
 void Canvas::generateMipmaps()

+ 12 - 135
src/modules/graphics/opengl/Image.cpp

@@ -34,37 +34,17 @@ namespace opengl
 {
 
 Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
-	: love::graphics::Image(Slices(textype), settings, false)
+	: love::graphics::Image(textype, format, width, height, slices, settings)
 	, texture(0)
-	, compressed(false)
-	, usingDefaultTexture(false)
-	, textureMemorySize(0)
 {
-	if (isPixelFormatCompressed(format))
-		throw love::Exception("This constructor is only supported for non-compressed pixel formats.");
-
-	if (textype == TEXTURE_VOLUME)
-		depth = slices;
-	else if (textype == TEXTURE_2D_ARRAY)
-		layers = slices;
-
-	init(format, width, height, settings);
+	loadVolatile();
 }
 
 Image::Image(const Slices &slices, const Settings &settings)
-	: love::graphics::Image(slices, settings, true)
+	: love::graphics::Image(slices, settings)
 	, texture(0)
-	, compressed(false)
-	, usingDefaultTexture(false)
-	, textureMemorySize(0)
 {
-	if (texType == TEXTURE_2D_ARRAY)
-		this->layers = data.getSliceCount();
-	else if (texType == TEXTURE_VOLUME)
-		this->depth = data.getSliceCount();
-
-	love::image::ImageDataBase *slice = data.get(0, 0);
-	init(slice->getFormat(), slice->getWidth(), slice->getHeight(), settings);
+	loadVolatile();
 }
 
 Image::~Image()
@@ -72,33 +52,13 @@ Image::~Image()
 	unloadVolatile();
 }
 
-void Image::init(PixelFormat fmt, int w, int h, const Settings &settings)
-{
-	pixelWidth = w;
-	pixelHeight = h;
-
-	width  = (int) (pixelWidth / settings.pixeldensity + 0.5);
-	height = (int) (pixelHeight / settings.pixeldensity + 0.5);
-
-	mipmapCount = mipmapsType == MIPMAPS_NONE ? 1 : getMipmapCount(w, h);
-	format = fmt;
-	compressed = isPixelFormatCompressed(format);
-
-	if (compressed && mipmapsType == MIPMAPS_GENERATED)
-		mipmapsType = MIPMAPS_NONE;
-
-	if (getMipmapCount() > 1)
-		filter.mipmap = defaultMipmapFilter;
-
-	initQuad();
-	loadVolatile();
-}
-
 void Image::generateMipmaps()
 {
 	if (getMipmapCount() > 1 && !isCompressed() &&
 		(GLAD_ES_VERSION_2_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_EXT_framebuffer_object))
 	{
+		gl.bindTextureToUnit(this, 0, false);
+
 		GLenum gltextype = OpenGL::getGLTextureType(texType);
 
 		if (gl.bugs.generateMipmapsRequiresTexture2DEnable)
@@ -189,6 +149,10 @@ void Image::loadData()
 
 void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t size, const Rect &r, int level, int slice)
 {
+	OpenGL::TempDebugGroup debuggroup("Image data upload");
+
+	gl.bindTextureToUnit(this, 0, false);
+
 	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, false, sRGB);
 	GLenum gltarget = OpenGL::getGLTextureType(texType);
 
@@ -214,18 +178,6 @@ void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t siz
 	}
 }
 
-void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice)
-{
-	love::image::ImageData *id = dynamic_cast<love::image::ImageData *>(d);
-
-	love::thread::EmptyLock lock;
-	if (id != nullptr)
-		lock.setLock(id->getMutex());
-
-	Rect rect = {0, 0, d->getWidth(), d->getHeight()};
-	uploadByteData(d->getFormat(), d->getData(), d->getSize(), rect, level, slice);
-}
-
 bool Image::loadVolatile()
 {
 	if (texture != 0)
@@ -343,67 +295,6 @@ void Image::unloadVolatile()
 	textureMemorySize = 0;
 }
 
-void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps)
-{
-	// No effect if the texture hasn't been created yet.
-	if (getHandle() == 0 || usingDefaultTexture)
-		return;
-
-	if (d->getFormat() != getPixelFormat())
-		throw love::Exception("Pixel formats must match.");
-
-	if (mipmap < 0 || (mipmapsType != MIPMAPS_DATA && mipmap > 0) || mipmap >= getMipmapCount())
-		throw love::Exception("Invalid image mipmap index.");
-
-	if (slice < 0 || (texType == TEXTURE_CUBE && slice >= 6)
-		|| (texType == TEXTURE_VOLUME && slice >= std::max(getDepth() >> mipmap, 1))
-		|| (texType == TEXTURE_2D_ARRAY && slice >= getLayerCount()))
-	{
-		throw love::Exception("Invalid image slice index.");
-	}
-
-	love::image::ImageDataBase *oldd = data.get(slice, mipmap);
-
-	if (oldd == nullptr)
-		throw love::Exception("Image does not store ImageData!");
-
-	int w = d->getWidth();
-	int h = d->getHeight();
-
-	if (w != oldd->getWidth() || h != oldd->getHeight())
-		throw love::Exception("Dimensions must match the texture's dimensions for the specified mipmap level.");
-
-	Graphics::flushStreamDrawsGlobal();
-
-	d->retain();
-	oldd->release();
-
-	data.set(slice, mipmap, d);
-
-	OpenGL::TempDebugGroup debuggroup("Image replace pixels");
-
-	gl.bindTextureToUnit(this, 0, false);
-
-	uploadImageData(d, mipmap, slice);
-
-	if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
-		generateMipmaps();
-}
-
-void Image::replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps)
-{
-	Graphics::flushStreamDrawsGlobal();
-
-	OpenGL::TempDebugGroup debuggroup("Image replace pixels");
-
-	gl.bindTextureToUnit(this, 0, false);
-
-	uploadByteData(format, data, size, rect, mipmap, slice);
-
-	if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
-		generateMipmaps();
-}
-
 ptrdiff_t Image::getHandle() const
 {
 	return texture;
@@ -476,8 +367,9 @@ bool Image::setMipmapSharpness(float sharpness)
 	Graphics::flushStreamDrawsGlobal();
 
 	float maxbias = gl.getMaxLODBias();
+
 	if (maxbias > 0.01f)
-		maxbias -= 0.0f;
+		maxbias -= 0.01f;
 
 	mipmapSharpness = std::min(std::max(sharpness, -maxbias), maxbias);
 
@@ -489,21 +381,6 @@ bool Image::setMipmapSharpness(float sharpness)
 	return true;
 }
 
-bool Image::isFormatLinear() const
-{
-	return isGammaCorrect() && !sRGB;
-}
-
-bool Image::isCompressed() const
-{
-	return compressed;
-}
-
-Image::MipmapsType Image::getMipmapsType() const
-{
-	return mipmapsType;
-}
-
 bool Image::isFormatSupported(PixelFormat pixelformat)
 {
 	return OpenGL::isPixelFormatSupported(pixelformat, false, true, false);

+ 2 - 20
src/modules/graphics/opengl/Image.h

@@ -54,38 +54,20 @@ public:
 
 	bool setMipmapSharpness(float sharpness) override;
 
-	void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps) override;
-	void replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps) override;
-
-	bool isFormatLinear() const override;
-	bool isCompressed() const override;
-	MipmapsType getMipmapsType() const override;
-
 	static bool isFormatSupported(PixelFormat pixelformat);
 	static bool hasSRGBSupport();
 
 private:
 
-	void init(PixelFormat fmt, int w, int h, const Settings &settings);
+	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, const Rect &rect, int level, int slice) override;
+	void generateMipmaps() override;
 
-	void generateMipmaps();
 	void loadDefaultTexture();
 	void loadData();
-	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, const Rect &rect, int level, int slice);
-	void uploadImageData(love::image::ImageDataBase *d, int level, int slice);
 
 	// OpenGL texture identifier.
 	GLuint texture;
 
-	// Whether this Image is using a compressed texture.
-	bool compressed;
-
-	// True if the image wasn't able to be properly created and it had to fall
-	// back to a default texture.
-	bool usingDefaultTexture;
-
-	size_t textureMemorySize;
-
 }; // Image
 
 } // opengl