/* Manually insert an image into the cache, useful to avoid texture-to-image
* conversion whenever we can intercept it.
*/
-void guiScalingCache(io::path key, video::IVideoDriver *driver, video::IImage *value)
+void guiScalingCache(const io::path &key, video::IVideoDriver *driver, video::IImage *value)
{
if (!g_settings->getBool("gui_scaling_filter"))
return;
if (!g_settings->getBool("gui_scaling_filter_txr2img"))
return src;
srcimg = driver->createImageFromData(src->getColorFormat(),
- src->getSize(), src->lock(), false);
+ src->getSize(), src->lock(video::ETLM_READ_ONLY), false);
src->unlock();
g_imgCache[origname] = srcimg;
}
(u32)destrect.getHeight()));
imageScaleNNAA(srcimg, srcrect, destimg);
-#ifdef __ANDROID__
- // Android is very picky about textures being powers of 2, so expand
- // the image dimensions to the next power of 2, if necessary, for
- // that platform.
- video::IImage *po2img = driver->createImage(src->getColorFormat(),
- core::dimension2d<u32>(npot2((u32)destrect.getWidth()),
- npot2((u32)destrect.getHeight())));
- po2img->fill(video::SColor(0, 0, 0, 0));
- destimg->copyTo(po2img);
- destimg->drop();
- destimg = po2img;
+#if ENABLE_GLES
+ // Some platforms are picky about textures being powers of 2, so expand
+ // the image dimensions to the next power of 2, if necessary.
+ if (!driver->queryFeature(video::EVDF_TEXTURE_NPOT)) {
+ video::IImage *po2img = driver->createImage(src->getColorFormat(),
+ core::dimension2d<u32>(npot2((u32)destrect.getWidth()),
+ npot2((u32)destrect.getHeight())));
+ po2img->fill(video::SColor(0, 0, 0, 0));
+ destimg->copyTo(po2img);
+ destimg->drop();
+ destimg = po2img;
+ }
#endif
// Convert the scaled image back into a texture.
- scaled = driver->addTexture(scalename, destimg, NULL);
+ scaled = driver->addTexture(scalename, destimg);
destimg->drop();
g_txrCache[scalename] = scaled;
driver->draw2DImage(scaled, destrect, mysrcrect, cliprect, colors, usealpha);
}
+
+void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture,
+ const core::rect<s32> &rect, const core::rect<s32> &middle,
+ const core::rect<s32> *cliprect, const video::SColor *const colors)
+{
+ auto originalSize = texture->getOriginalSize();
+ core::vector2di lowerRightOffset = core::vector2di(originalSize.Width, originalSize.Height) - middle.LowerRightCorner;
+
+ for (int y = 0; y < 3; ++y) {
+ for (int x = 0; x < 3; ++x) {
+ core::rect<s32> src({0, 0}, originalSize);
+ core::rect<s32> dest = rect;
+
+ switch (x) {
+ case 0:
+ dest.LowerRightCorner.X = rect.UpperLeftCorner.X + middle.UpperLeftCorner.X;
+ src.LowerRightCorner.X = middle.UpperLeftCorner.X;
+ break;
+
+ case 1:
+ dest.UpperLeftCorner.X += middle.UpperLeftCorner.X;
+ dest.LowerRightCorner.X -= lowerRightOffset.X;
+ src.UpperLeftCorner.X = middle.UpperLeftCorner.X;
+ src.LowerRightCorner.X = middle.LowerRightCorner.X;
+ break;
+
+ case 2:
+ dest.UpperLeftCorner.X = rect.LowerRightCorner.X - lowerRightOffset.X;
+ src.UpperLeftCorner.X = middle.LowerRightCorner.X;
+ break;
+ }
+
+ switch (y) {
+ case 0:
+ dest.LowerRightCorner.Y = rect.UpperLeftCorner.Y + middle.UpperLeftCorner.Y;
+ src.LowerRightCorner.Y = middle.UpperLeftCorner.Y;
+ break;
+
+ case 1:
+ dest.UpperLeftCorner.Y += middle.UpperLeftCorner.Y;
+ dest.LowerRightCorner.Y -= lowerRightOffset.Y;
+ src.UpperLeftCorner.Y = middle.UpperLeftCorner.Y;
+ src.LowerRightCorner.Y = middle.LowerRightCorner.Y;
+ break;
+
+ case 2:
+ dest.UpperLeftCorner.Y = rect.LowerRightCorner.Y - lowerRightOffset.Y;
+ src.UpperLeftCorner.Y = middle.LowerRightCorner.Y;
+ break;
+ }
+
+ draw2DImageFilterScaled(driver, texture, dest, src, cliprect, colors, true);
+ }
+ }
+}