diff --git a/src/client/lightview.cpp b/src/client/lightview.cpp index 792e2431cc..1e6f2caaa1 100644 --- a/src/client/lightview.cpp +++ b/src/client/lightview.cpp @@ -30,6 +30,7 @@ LightView::LightView(const Size& size) : m_pool(g_drawPool.get(DrawPoolType::LIGHT)) { g_mainDispatcher.addEvent([this, size] { m_texture = std::make_shared(size); + m_texture->setCached(true); m_texture->setSmooth(true); }); } diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index c223906d78..e852e0d98e 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -796,6 +796,7 @@ void ThingType::loadTexture(const int animationPhase) m_opaque = !fullImage->hasTransparentPixel(); textureData.source = std::make_shared(fullImage, true, false); + textureData.source->setCached(true); } Size ThingType::getBestTextureDimension(int w, int h, const int count) diff --git a/src/client/thingtype.h b/src/client/thingtype.h index d0a70f8ef3..a86d22e813 100644 --- a/src/client/thingtype.h +++ b/src/client/thingtype.h @@ -451,8 +451,10 @@ class ThingType final : public LuaObject const Timer getLastTimeUsage() const { return m_lastTimeUsage; } void unload() { - for (auto& data : m_textureData) + for (auto& data : m_textureData) { + if (data.source) data.source->setCached(false); data.source = nullptr; + } } PLAYER_ACTION getDefaultAction() { return m_defaultAction; } diff --git a/src/client/uisprite.cpp b/src/client/uisprite.cpp index b62e220990..b777e5faf1 100644 --- a/src/client/uisprite.cpp +++ b/src/client/uisprite.cpp @@ -62,7 +62,9 @@ void UISprite::setSpriteId(const int id) } const auto& image = g_sprites.getSpriteImage(id); + if (m_sprite) m_sprite->setCached(false); m_sprite = image ? std::make_shared(image) : nullptr; + m_sprite->setCached(true); } void UISprite::onStyleApply(const std::string_view styleName, const OTMLNodePtr& styleNode) diff --git a/src/framework/graphics/animatedtexture.h b/src/framework/graphics/animatedtexture.h index f808a7c1ed..48e73020d9 100644 --- a/src/framework/graphics/animatedtexture.h +++ b/src/framework/graphics/animatedtexture.h @@ -39,6 +39,11 @@ class AnimatedTexture final : public Texture void setSmooth(bool smooth) override; void setRepeat(bool repeat) override; + void setCached(bool v) override { + Texture::setCached(v); + for (const auto& frame : m_frames) + frame->setCached(v); + } uint32_t getNumPlays() const { return m_numPlays; } void setNumPlays(const uint32_t n) { m_numPlays = n; } diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index 96db29b8c0..c615384ab6 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -30,15 +30,18 @@ DrawPool* DrawPool::create(const DrawPoolType type) if (type == DrawPoolType::MAP) { pool->m_framebuffer->m_useAlphaWriting = false; pool->m_framebuffer->disableBlend(); - } else if (type == DrawPoolType::FOREGROUND) { + } + else if (type == DrawPoolType::FOREGROUND) { pool->setFPS(10); // creates a temporary framebuffer with smoothing. pool->m_temporaryFramebuffers.emplace_back(std::make_shared()); } - } else if (type == DrawPoolType::LIGHT) { + } + else if (type == DrawPoolType::LIGHT) { pool->m_hashCtrl = true; - } else { + } + else { pool->m_alwaysGroupDrawings = true; // CREATURE_INFORMATION & TEXT pool->setFPS(60); } @@ -58,7 +61,8 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod&& m if (m_type == DrawPoolType::FOREGROUND) { order = FIRST; agroup = false; - } else if (m_type == DrawPoolType::MAP && order == FIRST && !conductor.agroup) + } + else if (m_type == DrawPoolType::MAP && order == FIRST && !conductor.agroup) order = THIRD; if (agroup) { @@ -72,7 +76,8 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod&& m coords->append(coordsBuffer.get()); else addCoords(coords, method); - } else { + } + else { bool addNewObj = true; auto& list = m_objects[order]; @@ -94,7 +99,8 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod&& m if (coordsBuffer) { draw.coords->append(coordsBuffer.get()); - } else + } + else addCoords(draw.coords.get(), method); } } @@ -106,13 +112,17 @@ void DrawPool::addCoords(CoordsBuffer* buffer, const DrawMethod& method) { if (method.type == DrawMethodType::BOUNDING_RECT) { buffer->addBoudingRect(method.dest, method.intValue); - } else if (method.type == DrawMethodType::RECT) { + } + else if (method.type == DrawMethodType::RECT) { buffer->addRect(method.dest, method.src); - } else if (method.type == DrawMethodType::TRIANGLE) { + } + else if (method.type == DrawMethodType::TRIANGLE) { buffer->addTriangle(method.a, method.b, method.c); - } else if (method.type == DrawMethodType::UPSIDEDOWN_RECT) { + } + else if (method.type == DrawMethodType::UPSIDEDOWN_RECT) { buffer->addUpsideDownRect(method.dest, method.src); - } else if (method.type == DrawMethodType::REPEATED_RECT) { + } + else if (method.type == DrawMethodType::REPEATED_RECT) { buffer->addRepeatedRects(method.dest, method.src); } } @@ -157,9 +167,11 @@ bool DrawPool::updateHash(const DrawMethod& method, const TexturePtr& texture, c if (!method.a.isNull()) stdext::hash_union(hash, method.a.hash()); if (!method.b.isNull()) stdext::hash_union(hash, method.b.hash()); if (!method.c.isNull()) stdext::hash_union(hash, method.c.hash()); - } else if (method.type == DrawMethodType::BOUNDING_RECT) { + } + else if (method.type == DrawMethodType::BOUNDING_RECT) { if (method.intValue) stdext::hash_combine(hash, method.intValue); - } else { + } + else { if (method.dest.isValid()) stdext::hash_union(hash, method.dest.hash()); if (method.src.isValid()) stdext::hash_union(hash, method.src.hash()); } @@ -179,9 +191,10 @@ DrawPool::PoolState DrawPool::getState(const TexturePtr& texture, const Color& c PoolState copy = getCurrentState(); if (copy.color != color) copy.color = color; if (texture) { - if (texture->isEmpty() || m_type == DrawPoolType::FOREGROUND) { + if (texture->isEmpty() || !texture->isCached()) { copy.texture = texture; - } else { + } + else { copy.textureId = texture->getId(); copy.textureMatrixId = texture->getTransformMatrixId(); } @@ -225,7 +238,8 @@ void DrawPool::setShaderProgram(const PainterShaderProgramPtr& shaderProgram, co getCurrentState().shaderProgram = shaderProgram.get(); getCurrentState().action = action; - } else { + } + else { getCurrentState().shaderProgram = nullptr; getCurrentState().action = nullptr; } @@ -332,7 +346,8 @@ void DrawPool::PoolState::execute() const { if (texture) { texture->create(); g_painter->setTexture(texture->getId(), texture->getTransformMatrixId()); - } else + } + else g_painter->setTexture(textureId, textureMatrixId); } @@ -377,7 +392,7 @@ void DrawPool::bindFrameBuffer(const Size& size, const Color& color) const auto& frame = getTemporaryFrameBuffer(frameIndex); frame->resize(size); frame->bind(); - }); + }); } void DrawPool::releaseFrameBuffer(const Rect& dest) { @@ -388,7 +403,7 @@ void DrawPool::releaseFrameBuffer(const Rect& dest) frame->release(); drawState.execute(); frame->draw(dest); - }); + }); if (hasFrameBuffer() && !dest.isNull()) m_hashCtrl.put(dest.hash()); --m_bindedFramebuffers; diff --git a/src/framework/graphics/texture.h b/src/framework/graphics/texture.h index f3d39c04c1..56b6461a49 100644 --- a/src/framework/graphics/texture.h +++ b/src/framework/graphics/texture.h @@ -59,6 +59,8 @@ class Texture bool isEmpty() const { return m_id == 0; } bool hasRepeat() const { return getProp(repeat); } bool hasMipmaps() const { return getProp(hasMipMaps); } + bool isCached() const { return getProp(cached); } + virtual void setCached(bool v) { setProp(cached, v); } virtual bool isAnimatedTexture() const { return false; } bool setupSize(const Size& size); @@ -91,7 +93,8 @@ class Texture upsideDown = 1 << 2, repeat = 1 << 3, compress = 1 << 4, - buildMipmaps = 1 << 5 + buildMipmaps = 1 << 5, + cached = 1 << 6 }; uint16_t m_props{ 0 }; diff --git a/src/framework/graphics/texturemanager.cpp b/src/framework/graphics/texturemanager.cpp index ed8d506ced..34ab6c4c86 100644 --- a/src/framework/graphics/texturemanager.cpp +++ b/src/framework/graphics/texturemanager.cpp @@ -91,7 +91,7 @@ void TextureManager::liveReload() tex->uploadPixels(image, tex->hasMipmaps()); tex->setTime(stdext::time()); } - }, 1000); + }, 1000); } TexturePtr TextureManager::getTexture(const std::string& fileName, const bool smooth) @@ -131,7 +131,8 @@ TexturePtr TextureManager::getTexture(const std::string& fileName, const bool sm std::stringstream fin; g_resources.readFileStream(filePathEx, fin); texture = loadTexture(fin); - } catch (const stdext::exception& e) { + } + catch (const stdext::exception& e) { g_logger.error("Unable to load texture '{}': {}", fileName, e.what()); texture = g_textures.getEmptyTexture(); } @@ -139,6 +140,7 @@ TexturePtr TextureManager::getTexture(const std::string& fileName, const bool sm if (texture) { texture->setTime(stdext::time()); texture->setSmooth(smooth); + texture->setCached(true); std::unique_lock l(m_mutex); m_textures[filePath] = texture; } @@ -171,7 +173,8 @@ TexturePtr TextureManager::loadTexture(std::stringstream& file) const auto& animatedTexture = std::make_shared(imageSize, frames, framesDelay, apng.num_plays); std::scoped_lock l(m_mutex); texture = m_animatedTextures.emplace_back(animatedTexture); - } else { + } + else { const auto& image = std::make_shared(imageSize, apng.bpp, apng.pdata); texture = std::make_shared(image, false, false); } diff --git a/src/framework/ui/uiqrcode.cpp b/src/framework/ui/uiqrcode.cpp index d5d285cf95..815b7692e7 100644 --- a/src/framework/ui/uiqrcode.cpp +++ b/src/framework/ui/uiqrcode.cpp @@ -45,7 +45,9 @@ void UIQrCode::setCode(const std::string& code, const int border) } m_qrCode = code; + if (m_imageTexture) m_imageTexture->setCached(false); m_imageTexture = std::make_shared(Image::fromQRCode(code, border)); + m_imageTexture->setCached(true); if (m_imageTexture && (!m_rect.isValid() || isImageAutoResize())) { const auto& imageSize = m_imageTexture->getSize();