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

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-04-30 00:01:23 -03:00
parent 621fb24ba1
commit 16f5557131
5 changed files with 171 additions and 168 deletions
+128
View File
@@ -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)
{