From c58de0a91f2f5c91e48bc4fe629903d79d7571d2 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 21 Apr 2021 11:43:01 +0800 Subject: [PATCH] Make GEGLTexture texture locking read only --- lib/graphics_engine/src/ge_gl_texture.cpp | 26 +++++++++++--------- lib/graphics_engine/src/ge_gl_texture.hpp | 13 ++++++++-- src/font/font_with_face.cpp | 6 ++--- src/guiengine/widgets/icon_button_widget.cpp | 15 ++++++++--- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/lib/graphics_engine/src/ge_gl_texture.cpp b/lib/graphics_engine/src/ge_gl_texture.cpp index 951069846..1b9789eb2 100644 --- a/lib/graphics_engine/src/ge_gl_texture.cpp +++ b/lib/graphics_engine/src/ge_gl_texture.cpp @@ -16,9 +16,9 @@ namespace GE GEGLTexture::GEGLTexture(const std::string& path, std::function image_mani) : video::ITexture(path.c_str()), m_image_mani(image_mani), - m_single_channel(false), m_texture_name(0), m_texture_size(0), + m_locked_data(NULL), m_texture_name(0), m_texture_size(0), m_driver_type(GE::getDriver()->getDriverType()), - m_disable_reload(false) + m_disable_reload(false), m_single_channel(false) { reload(); } // GEGLTexture @@ -26,9 +26,9 @@ GEGLTexture::GEGLTexture(const std::string& path, // ---------------------------------------------------------------------------- GEGLTexture::GEGLTexture(video::IImage* img, const std::string& name) : video::ITexture(name.c_str()), m_image_mani(nullptr), - m_single_channel(false), m_texture_name(0), m_texture_size(0), + m_locked_data(NULL), m_texture_name(0), m_texture_size(0), m_driver_type(GE::getDriver()->getDriverType()), - m_disable_reload(true) + m_disable_reload(true), m_single_channel(false) { if (!img) return; @@ -44,9 +44,9 @@ GEGLTexture::GEGLTexture(video::IImage* img, const std::string& name) GEGLTexture::GEGLTexture(const std::string& name, unsigned int size, bool single_channel) : video::ITexture(name.c_str()), m_image_mani(nullptr), - m_single_channel(false), m_texture_name(0), m_texture_size(0), + m_locked_data(NULL), m_texture_name(0), m_texture_size(0), m_driver_type(GE::getDriver()->getDriverType()), - m_disable_reload(true) + m_disable_reload(true), m_single_channel(false) { glGenTextures(1, &m_texture_name); m_orig_size.Width = size; @@ -141,23 +141,27 @@ void GEGLTexture::upload(uint8_t* data) // ---------------------------------------------------------------------------- void* GEGLTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level) { + if (mode != video::ETLM_READ_ONLY) + return NULL; + if (m_driver_type == video::EDT_OGLES2 || !glGetTexImage) { video::IImage* img = getResizedImage(NamedPath.getPtr()); if (!img) return NULL; img->setDeleteMemory(false); - void* data = img->lock(); + m_locked_data = (uint8_t*)img->lock(); + img->unlock(); img->drop(); - return data; + return m_locked_data; } - uint8_t* pixels = new uint8_t[m_size.Width * m_size.Height * 4](); + m_locked_data = new uint8_t[m_size.Width * m_size.Height * 4](); GLint tmp_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmp_texture); glBindTexture(GL_TEXTURE_2D, m_texture_name); - glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_locked_data); glBindTexture(GL_TEXTURE_2D, tmp_texture); - return pixels; + return m_locked_data; } // lock //----------------------------------------------------------------------------- diff --git a/lib/graphics_engine/src/ge_gl_texture.hpp b/lib/graphics_engine/src/ge_gl_texture.hpp index 02fecce8a..869e09eb3 100644 --- a/lib/graphics_engine/src/ge_gl_texture.hpp +++ b/lib/graphics_engine/src/ge_gl_texture.hpp @@ -18,7 +18,7 @@ private: std::function m_image_mani; - bool m_single_channel; + uint8_t* m_locked_data; GLuint m_texture_name; @@ -28,6 +28,8 @@ private: const bool m_disable_reload; + bool m_single_channel; + // ------------------------------------------------------------------------ void upload(uint8_t* data); // ------------------------------------------------------------------------ @@ -49,7 +51,14 @@ public: virtual void* lock(video::E_TEXTURE_LOCK_MODE mode = video::ETLM_READ_WRITE, u32 mipmap_level = 0); // ------------------------------------------------------------------------ - virtual void unlock() {} + virtual void unlock() + { + if (m_locked_data) + { + delete [] m_locked_data; + m_locked_data = NULL; + } + } // ------------------------------------------------------------------------ virtual const core::dimension2d& getOriginalSize() const { return m_orig_size; } diff --git a/src/font/font_with_face.cpp b/src/font/font_with_face.cpp index 476968fae..d3cf976a4 100644 --- a/src/font/font_with_face.cpp +++ b/src/font/font_with_face.cpp @@ -370,16 +370,16 @@ void FontWithFace::dumpGlyphPage(const std::string& name) video::ITexture* tex = m_spritebank->getTexture(i); core::dimension2d size = tex->getSize(); video::ECOLOR_FORMAT col_format = tex->getColorFormat(); - void* data = tex->lock(); + void* data = tex->lock(video::ETLM_READ_ONLY); if (!data) continue; video::IImage* image = irr_driver->getVideoDriver() ->createImageFromData(col_format, size, data, - true/*ownForeignMemory*/); - tex->unlock(); + false/*ownForeignMemory*/); irr_driver->getVideoDriver()->writeImageToFile(image, std::string (name + "_" + StringUtils::toString(i) + ".png").c_str()); image->drop(); + tex->unlock(); } #endif } // dumpGlyphPage diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 684ec659a..de6471299 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -376,12 +376,16 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur SColor c; u32 g; + void* tex_data = texture->lock(video::ETLM_READ_ONLY); + if (!tex_data) + return texture; video::IVideoDriver* driver = irr_driver->getVideoDriver(); video::IImage* image = driver->createImageFromData - (video::ECF_A8R8G8B8, texture->getSize(), texture->lock(), - true/*ownForeignMemory*/); - texture->unlock(); + (video::ECF_A8R8G8B8, texture->getSize(), tex_data, + false/*ownForeignMemory*/); + // GE::createTexture image will drop the image + image->grab(); //Turn the image into grayscale for (u32 x = 0; x < image->getDimension().Width; x++) { @@ -393,7 +397,10 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur image->setPixel(x, y, c); } } - return stkm->addTexture(GE::createTexture(image, name)); + video::ITexture* disabled_tex = GE::createTexture(image, name); + image->drop(); + texture->unlock(); + return stkm->addTexture(disabled_tex); } return stkm->getTexture(name); #else