Browse Source

Move some OpenGL-specific Image code into the GL backend

Alex Szpakowski 5 years ago
parent
commit
e0ffdfc1ba

+ 7 - 19
src/modules/graphics/Image.cpp

@@ -36,7 +36,6 @@ int Image::imageCount = 0;
 Image::Image(const Slices &data, const Settings &settings, bool validatedata)
 	: Texture(data.getTextureType())
 	, settings(settings)
-	, data(data)
 	, mipmapsType(settings.mipmaps ? MIPMAPS_GENERATED : MIPMAPS_NONE)
 	, sRGB(isGammaCorrect() && !settings.linear)
 	, usingDefaultTexture(false)
@@ -63,11 +62,11 @@ Image::Image(const Slices &slices, const Settings &settings)
 	: Image(slices, settings, true)
 {
 	if (texType == TEXTURE_2D_ARRAY)
-		this->layers = data.getSliceCount();
+		this->layers = slices.getSliceCount();
 	else if (texType == TEXTURE_VOLUME)
-		this->depth = data.getSliceCount();
+		this->depth = slices.getSliceCount();
 
-	love::image::ImageDataBase *slice = data.get(0, 0);
+	love::image::ImageDataBase *slice = slices.get(0, 0);
 	init(slice->getFormat(), slice->getWidth(), slice->getHeight(), settings);
 }
 
@@ -121,7 +120,7 @@ void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice,
 		lock.setLock(id->getMutex());
 
 	Rect rect = {x, y, d->getWidth(), d->getHeight()};
-	uploadByteData(d->getFormat(), d->getData(), d->getSize(), level, slice, rect);
+	uploadByteData(d->getFormat(), d->getData(), d->getSize(), level, slice, rect, d);
 }
 
 void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, int x, int y, bool reloadmipmaps)
@@ -154,19 +153,8 @@ void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap,
 		throw love::Exception("Invalid rectangle dimensions (x=%d, y=%d, w=%d, h=%d) for %dx%d Image.", rect.x, rect.y, rect.w, rect.h, mipw, miph);
 	}
 
-	love::image::ImageDataBase *oldd = data.get(slice, mipmap);
-
-	if (oldd == nullptr)
-		throw love::Exception("Image does not store ImageData!");
-
-	Rect currect = {0, 0, oldd->getWidth(), oldd->getHeight()};
-
-	// We can only replace the internal Data (used when reloading due to setMode)
-	// if the dimensions match. We also don't currently support partial updates
-	// of compressed textures.
-	if (rect == currect)
-		data.set(slice, mipmap, d);
-	else if (isPixelFormatCompressed(d->getFormat()))
+	// We don't currently support partial updates of compressed textures.
+	if (isPixelFormatCompressed(d->getFormat()) && (rect.x != 0 || rect.y != 0 || rect.w != mipw || rect.h != miph))
 		throw love::Exception("Compressed textures only support replacing the entire Image.");
 
 	Graphics::flushStreamDrawsGlobal();
@@ -181,7 +169,7 @@ void Image::replacePixels(const void *data, size_t size, int slice, int mipmap,
 {
 	Graphics::flushStreamDrawsGlobal();
 
-	uploadByteData(format, data, size, mipmap, slice, rect);
+	uploadByteData(format, data, size, mipmap, slice, rect, nullptr);
 
 	if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
 		generateMipmaps();

+ 1 - 3
src/modules/graphics/Image.h

@@ -113,15 +113,13 @@ protected:
 	Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings);
 
 	void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y);
-	virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) = 0;
+	virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) = 0;
 
 	virtual void generateMipmaps() = 0;
 
 	// The settings used to initialize this Image.
 	Settings settings;
 
-	Slices data;
-
 	MipmapsType mipmapsType;
 	bool sRGB;
 

+ 19 - 7
src/modules/graphics/opengl/Image.cpp

@@ -35,6 +35,7 @@ namespace opengl
 
 Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
 	: love::graphics::Image(textype, format, width, height, slices, settings)
+	, slices(textype)
 	, texture(0)
 {
 	loadVolatile();
@@ -42,6 +43,7 @@ Image::Image(TextureType textype, PixelFormat format, int width, int height, int
 
 Image::Image(const Slices &slices, const Settings &settings)
 	: love::graphics::Image(slices, settings)
+	, slices(slices)
 	, texture(0)
 {
 	loadVolatile();
@@ -85,7 +87,7 @@ void Image::loadDefaultTexture()
 	int slices = texType == TEXTURE_CUBE ? 6 : 1;
 	Rect rect = {0, 0, 2, 2};
 	for (int slice = 0; slice < slices; slice++)
-		uploadByteData(PIXELFORMAT_RGBA8_UNORM, px, sizeof(px), 0, slice, rect);
+		uploadByteData(PIXELFORMAT_RGBA8_UNORM, px, sizeof(px), 0, slice, rect, nullptr);
 }
 
 void Image::loadData()
@@ -120,8 +122,8 @@ void Image::loadData()
 
 			if (texType == TEXTURE_2D_ARRAY || texType == TEXTURE_VOLUME)
 			{
-				for (int slice = 0; slice < data.getSliceCount(mip); slice++)
-					mipsize += data.get(slice, mip)->getSize();
+				for (int slice = 0; slice < slices.getSliceCount(mip); slice++)
+					mipsize += slices.get(slice, mip)->getSize();
 			}
 
 			GLenum gltarget = OpenGL::getGLTextureType(texType);
@@ -130,7 +132,7 @@ void Image::loadData()
 
 		for (int slice = 0; slice < slicecount; slice++)
 		{
-			love::image::ImageDataBase *id = data.get(slice, mip);
+			love::image::ImageDataBase *id = slices.get(slice, mip);
 
 			if (id != nullptr)
 				uploadImageData(id, mip, slice, 0, 0);
@@ -147,8 +149,18 @@ void Image::loadData()
 		generateMipmaps();
 }
 
-void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r)
+void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd)
 {
+	love::image::ImageDataBase *oldd = slices.get(slice, level);
+
+	// We can only replace the internal Data (used when reloading due to setMode)
+	// if the dimensions match.
+	if (imgd != nullptr && oldd != nullptr && oldd->getWidth() == imgd->getWidth()
+		&& oldd->getHeight() == imgd->getHeight())
+	{
+		slices.set(slice, level, imgd);
+	}
+
 	OpenGL::TempDebugGroup debuggroup("Image data upload");
 
 	gl.bindTextureToUnit(this, 0, false);
@@ -242,8 +254,8 @@ bool Image::loadVolatile()
 
 	int64 memsize = 0;
 
-	for (int slice = 0; slice < data.getSliceCount(0); slice++)
-		memsize += data.get(slice, 0)->getSize();
+	for (int slice = 0; slice < slices.getSliceCount(0); slice++)
+		memsize += slices.get(slice, 0)->getSize();
 
 	if (getMipmapCount() > 1)
 		memsize *= 1.33334;

+ 3 - 1
src/modules/graphics/opengl/Image.h

@@ -56,12 +56,14 @@ public:
 
 private:
 
-	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) override;
+	void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) override;
 	void generateMipmaps() override;
 
 	void loadDefaultTexture();
 	void loadData();
 
+	Slices slices;
+
 	// OpenGL texture identifier.
 	GLuint texture;