Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/client/spritemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,14 @@ ImagePtr SpriteManager::getSpriteImage(const int id, bool& isLoading)

const auto threadId = g_app.isLoadingAsyncTexture() ? stdext::getThreadId() : 0;
if (const auto& sf = m_spritesFiles[threadId % m_spritesFiles.size()]) {
if (g_app.isLoadingAsyncTexture() && sf->m_loadingState.exchange(SpriteLoadState::LOADING, std::memory_order_acq_rel) == SpriteLoadState::LOADING) {
if (sf->m_loadingState.exchange(SpriteLoadState::LOADING, std::memory_order_acq_rel) == SpriteLoadState::LOADING) {
isLoading = true;
return nullptr;
}

auto image = m_spritesHd ? getSpriteImageHd(id, sf->file) : getSpriteImage(id, sf->file);

if (g_app.isLoadingAsyncTexture())
sf->m_loadingState.store(SpriteLoadState::LOADED, std::memory_order_release);
sf->m_loadingState.store(SpriteLoadState::LOADED, std::memory_order_release);

return image;
}
Expand Down Expand Up @@ -273,8 +272,8 @@ ImagePtr SpriteManager::getSpriteImage(const int id, const FileStreamPtr& file)
int read = 0;
bool hasAlpha = false;

constexpr int MAX_PIXEL_BLOCK = 4096;
uint8_t tempBuffer[MAX_PIXEL_BLOCK * 4]; // 4 = max channels
static constexpr int MAX_PIXEL_BLOCK = 4096;
static thread_local uint8_t tempBuffer[MAX_PIXEL_BLOCK * 4]; // 4 = max channels

while (read < pixelDataSize && writePos < maxWriteSize) {
const uint16_t transparentPixels = file->getU16();
Expand Down
22 changes: 13 additions & 9 deletions src/framework/graphics/drawpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@
return pool;
}

void DrawPool::add(const Color& color, TexturePtr texture, DrawMethod&& method, const CoordsBufferPtr& coordsBuffer)
void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod&& method, const CoordsBufferPtr& coordsBuffer)
{
Texture* textureAtlas = nullptr;
if (m_atlas && texture && texture->isCached(m_atlas->getType())) {
const auto& atlas = texture->getAtlas(m_atlas->getType());
if (atlas->isEnabled()) {
texture = m_atlas->getTexture(atlas->layer, texture->isSmooth());
const auto region = texture->getAtlas(m_atlas->getType());
if (region->isEnabled()) {
textureAtlas = region->atlas;
if (method.src.isValid())
method.src = Rect(atlas->x + method.src.x(), atlas->y + method.src.y(), method.src.width(), method.src.height());
method.src = Rect(region->x + method.src.x(), region->y + method.src.y(), method.src.width(), method.src.height());
}
}

Expand All @@ -67,7 +68,7 @@
if (m_alwaysGroupDrawings) {
auto& coords = m_coords.try_emplace(getCurrentState().hash, nullptr).first->second;
if (!coords) {
auto state = getState(texture, color);
auto state = getState(texture, textureAtlas, color);
coords = list.emplace_back(std::move(state), getCoordsBuffer()).coords.get();
}

Expand All @@ -91,7 +92,7 @@
}

if (addNewObj) {
auto state = getState(texture, color);
auto state = getState(texture, textureAtlas, color);
auto& draw = list.emplace_back(std::move(state), getCoordsBuffer());

if (coordsBuffer) {
Expand Down Expand Up @@ -176,14 +177,17 @@
return true;
}

DrawPool::PoolState DrawPool::getState(const TexturePtr& texture, const Color& color)
DrawPool::PoolState DrawPool::getState(const TexturePtr& texture, Texture* textureAtlas, const Color& color)
{
PoolState copy = getCurrentState();

if (copy.color != color) copy.color = color;

if (texture) {
if (textureAtlas) {
copy.textureId = textureAtlas->getId();
copy.textureMatrixId = textureAtlas->getTransformMatrixId();
} else if (texture) {
if (texture->isEmpty() || !texture->canCacheInAtlas() || texture->canCacheInAtlas() && m_atlas) {

Check warning on line 190 in src/framework/graphics/drawpool.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-debug

suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
copy.texture = texture;
} else {
copy.textureId = texture->getId();
Expand Down
4 changes: 2 additions & 2 deletions src/framework/graphics/drawpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
return m_hashCtrl;
}

const auto getAtlas() const {

Check warning on line 141 in src/framework/graphics/drawpool.h

View workflow job for this annotation

GitHub Actions / emscripten-debug

'const' type qualifier on return type has no effect [-Wignored-qualifiers]

Check warning on line 141 in src/framework/graphics/drawpool.h

View workflow job for this annotation

GitHub Actions / emscripten-debug

'const' type qualifier on return type has no effect [-Wignored-qualifiers]
return m_atlas.get();
}

Expand Down Expand Up @@ -272,7 +272,7 @@
STATE_BLEND_EQUATION = 1 << 4,
};

void add(const Color& color, TexturePtr texture, DrawMethod&& method, const CoordsBufferPtr& coordsBuffer = nullptr);
void add(const Color& color, const TexturePtr& texture, DrawMethod&& method, const CoordsBufferPtr& coordsBuffer = nullptr);

void addAction(const std::function<void()>& action);
void bindFrameBuffer(const Size& size, const Color& color = Color::white);
Expand All @@ -281,7 +281,7 @@
void setFPS(const uint16_t fps) { m_refreshDelay = 1000 / fps; }

bool updateHash(const DrawMethod& method, const TexturePtr& texture, const Color& color, bool hasCoord);
PoolState getState(const TexturePtr& texture, const Color& color);
PoolState getState(const TexturePtr& texture, Texture* textureAtlas, const Color& color);

PoolState& getCurrentState() { return m_states[m_lastStateIndex]; }
const PoolState& getCurrentState() const { return m_states[m_lastStateIndex]; }
Expand Down
7 changes: 2 additions & 5 deletions src/framework/graphics/textureatlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ void TextureAtlas::addTexture(const TexturePtr& texture) {
region.layer,
static_cast<int16_t>(width),
static_cast<int16_t>(height),
texture->getTransformMatrixId()
texture->getTransformMatrixId(),
m_filterGroups[texture->isSmooth()].layers[region.layer].framebuffer->getTexture().get()
);

texture->m_atlas[m_type] = info.get();
Expand Down Expand Up @@ -115,8 +116,4 @@ void TextureAtlas::flush() {
}
}
}
}

TexturePtr TextureAtlas::getTexture(int layer, bool smooth) const {
return m_filterGroups[smooth].layers[layer].framebuffer->getTexture();
}
9 changes: 4 additions & 5 deletions src/framework/graphics/textureatlas.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ class AtlasRegion
int16_t width;
int16_t height;
uint16_t transformMatrixId;
std::atomic_bool enabled = false;
Texture* atlas;
std::atomic_bool enabled;

bool isEnabled() const {
return enabled.load(std::memory_order_acquire);
}

AtlasRegion(uint32_t tid, int16_t x, int16_t y, int8_t layer,
int16_t width, int16_t height, uint16_t transformId)
int16_t width, int16_t height, uint16_t transformId, Texture* atlas)
: textureID(tid), x(x), y(y), layer(layer),
width(width), height(height), transformMatrixId(transformId) {
width(width), height(height), transformMatrixId(transformId), atlas(atlas) {
}
};

Expand Down Expand Up @@ -77,8 +78,6 @@ class TextureAtlas
void addTexture(const TexturePtr& texture);
void removeTexture(uint32_t id, bool smooth);

TexturePtr getTexture(int layer, bool smooth) const;

Size getSize() const { return m_size; }

void flush();
Expand Down
18 changes: 9 additions & 9 deletions src/framework/ui/uitextedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ void UITextEdit::drawSelf(const DrawPoolType drawPane)
setProp(PropGlyphsMustRecache, false);

// Hack to fix font rendering in atlas
if (!m_atlased && g_drawPool.getAtlas() && m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType())) {
m_atlased = true;
update();
if (g_drawPool.getAtlas() && m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType()) != m_lastAtlasRegion) {
m_lastAtlasRegion = m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType());
update(false, true);
}

const int textLength = std::min<int>(m_glyphsCoords.size(), m_text.length());
Expand Down Expand Up @@ -133,7 +133,7 @@ void UITextEdit::drawSelf(const DrawPoolType drawPane)
}
}

void UITextEdit::update(const bool focusCursor)
void UITextEdit::update(const bool focusCursor, bool disableAreaUpdate)
{
if (!getProp(PropUpdatesEnabled))
return;
Expand Down Expand Up @@ -362,16 +362,16 @@ void UITextEdit::update(const bool focusCursor)
glyphScreenCoords.setRight(textScreenCoords.right());
}

// render glyph
m_glyphsCoords[i].first = glyphScreenCoords;
m_glyphsCoords[i].second = glyphTextureCoords;

TextureAtlas* atlas = nullptr;
if (g_drawPool.isValid())
atlas = g_drawPool.getAtlas();
else
atlas = g_drawPool.get(DrawPoolType::FOREGROUND)->getAtlas();

// render glyph
m_glyphsCoords[i].first = glyphScreenCoords;
m_glyphsCoords[i].second = glyphTextureCoords;

if (atlas) {
if (const auto region = m_font->getTexture()->getAtlas(atlas->getType()))
glyphTextureCoords = Rect(region->x + glyphTextureCoords.x(), region->y + glyphTextureCoords.y(), glyphTextureCoords.width(), glyphTextureCoords.height());
Expand All @@ -388,7 +388,7 @@ void UITextEdit::update(const bool focusCursor)
m_colorCoordsBuffer.emplace_back(Color(rgba), crds);
}

if (fireAreaUpdate)
if (!disableAreaUpdate && fireAreaUpdate)
onTextAreaUpdate(m_textVirtualOffset, m_textVirtualSize, m_textTotalSize);

repaint();
Expand Down
2 changes: 1 addition & 1 deletion src/framework/ui/uitextedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class UITextEdit final : public UIWidget
void drawSelf(DrawPoolType drawPane) override;

private:
void update(bool focusCursor = false);
void update(bool focusCursor = false, bool disableAreaUpdate = false);

public:
void setCursorPos(int pos);
Expand Down
4 changes: 2 additions & 2 deletions src/framework/ui/uiwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
UIWidget();
~UIWidget() override;
virtual void drawSelf(DrawPoolType drawPane);
virtual void draw(const Rect& visibleRect, DrawPoolType drawPane);

Check warning on line 87 in src/framework/ui/uiwidget.h

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-debug

‘virtual void UIWidget::draw(const Rect&, DrawPoolType)’ was hidden [-Woverloaded-virtual=]

Check warning on line 87 in src/framework/ui/uiwidget.h

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-debug

‘virtual void UIWidget::draw(const Rect&, DrawPoolType)’ was hidden [-Woverloaded-virtual=]

Check warning on line 87 in src/framework/ui/uiwidget.h

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-debug

‘virtual void UIWidget::draw(const Rect&, DrawPoolType)’ was hidden [-Woverloaded-virtual=]
protected:
virtual void drawChildren(const Rect& visibleRect, DrawPoolType drawPane);

Expand Down Expand Up @@ -508,7 +508,7 @@
void updateImageCache() { if (!m_imageCachedScreenCoords.isNull()) m_imageCachedScreenCoords = {}; }
void configureBorderImage() { setProp(PropImageBordered, true); updateImageCache(); }

std::vector<std::pair<Rect, Rect>> m_imageCoordsCache;
CoordsBufferPtr m_imageCoordsCache;

Rect m_imageCachedScreenCoords;

Expand Down Expand Up @@ -598,7 +598,7 @@
std::vector<std::pair<Color, CoordsBufferPtr>> m_colorCoordsBuffer;

float m_fontScale{ 1.f };
bool m_atlased{ false };
AtlasRegion* m_lastAtlasRegion = nullptr;

public:
void resizeToText();
Expand Down
54 changes: 32 additions & 22 deletions src/framework/ui/uiwidgetimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
#include <framework/graphics/textureatlas.h>
#include <framework/util/crypt.h>

void UIWidget::initImage() {}
void UIWidget::initImage() {
m_imageCoordsCache = std::make_shared<CoordsBuffer>();
}

void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
{
Expand Down Expand Up @@ -88,26 +90,40 @@ void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
}
}

void addImageRect(const TexturePtr& texture, const CoordsBufferPtr& coords, bool useRepeated, const Rect& dest, Rect src) {
if (const auto atlas = g_drawPool.getAtlas()) {
if (const auto region = texture->getAtlas(atlas->getType()))
src = Rect(region->x + src.x(), region->y + src.y(), src.width(), src.height());
}

if (useRepeated)
coords->addRepeatedRects(dest, src);
else
coords->addRect(dest, src);
};

void UIWidget::drawImage(const Rect& screenCoords)
{
if (!m_imageTexture || !screenCoords.isValid())
return;

// Hack to fix font rendering in atlas
if (!m_atlased && g_drawPool.getAtlas() && m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType())) {
m_atlased = true;
m_imageCachedScreenCoords = {};
if (g_drawPool.getAtlas() && m_imageTexture->getAtlas(g_drawPool.getAtlas()->getType()) != m_lastAtlasRegion) {
m_lastAtlasRegion = m_imageTexture->getAtlas(g_drawPool.getAtlas()->getType());
updateImageCache();
}
// cache vertex buffers
if (m_imageCachedScreenCoords != screenCoords) {
m_imageCachedScreenCoords = screenCoords;
m_imageCoordsCache.clear();
m_imageCoordsCache->clear();

Rect drawRect = screenCoords;
drawRect.translate(m_imageRect.topLeft());
if (m_imageRect.isValid())
drawRect.resize(m_imageRect.size());

const bool useRepeated = hasProp(PropImageBordered) || hasProp(PropImageRepeated);

auto clipRect = m_imageClipRect.isValid() ? m_imageClipRect : Rect(0, 0, m_imageTexture->getSize());

if (hasProp(PropImageBordered)) {
Expand All @@ -133,32 +149,32 @@ void UIWidget::drawImage(const Rect& screenCoords)
// first the center
if (centerSize.area() > 0) {
rectCoords = Rect(drawRect.left() + leftBorder.width(), drawRect.top() + topBorder.height(), centerSize);
m_imageCoordsCache.emplace_back(rectCoords, center);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, center);
}
// top left corner
rectCoords = Rect(drawRect.topLeft(), topLeftCorner.size());
m_imageCoordsCache.emplace_back(rectCoords, topLeftCorner);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, topLeftCorner);
// top
rectCoords = Rect(drawRect.left() + topLeftCorner.width(), drawRect.topLeft().y, centerSize.width(), topBorder.height());
m_imageCoordsCache.emplace_back(rectCoords, topBorder);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, topBorder);
// top right corner
rectCoords = Rect(drawRect.left() + topLeftCorner.width() + centerSize.width(), drawRect.top(), topRightCorner.size());
m_imageCoordsCache.emplace_back(rectCoords, topRightCorner);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, topRightCorner);
// left
rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height(), leftBorder.width(), centerSize.height());
m_imageCoordsCache.emplace_back(rectCoords, leftBorder);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, leftBorder);
// right
rectCoords = Rect(drawRect.left() + leftBorder.width() + centerSize.width(), drawRect.top() + topRightCorner.height(), rightBorder.width(), centerSize.height());
m_imageCoordsCache.emplace_back(rectCoords, rightBorder);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, rightBorder);
// bottom left corner
rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height() + centerSize.height(), bottomLeftCorner.size());
m_imageCoordsCache.emplace_back(rectCoords, bottomLeftCorner);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, bottomLeftCorner);
// bottom
rectCoords = Rect(drawRect.left() + bottomLeftCorner.width(), drawRect.top() + topBorder.height() + centerSize.height(), centerSize.width(), bottomBorder.height());
m_imageCoordsCache.emplace_back(rectCoords, bottomBorder);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, bottomBorder);
// bottom right corner
rectCoords = Rect(drawRect.left() + bottomLeftCorner.width() + centerSize.width(), drawRect.top() + topRightCorner.height() + centerSize.height(), bottomRightCorner.size());
m_imageCoordsCache.emplace_back(rectCoords, bottomRightCorner);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, rectCoords, bottomRightCorner);
} else {
if (isImageFixedRatio()) {
Size textureSize = m_imageTexture->getSize(),
Expand All @@ -175,25 +191,19 @@ void UIWidget::drawImage(const Rect& screenCoords)
clipRect = Rect(texCoordsOffset, textureClipSize);
}

m_imageCoordsCache.emplace_back(drawRect, clipRect);
addImageRect(m_imageTexture, m_imageCoordsCache, useRepeated, drawRect, clipRect);
}
}

// smooth is now enabled by default for all textures
//m_imageTexture->setSmooth(m_imageSmooth);
const bool useRepeated = hasProp(PropImageBordered) || hasProp(PropImageRepeated);

const auto& texture = m_imageTexture->isAnimatedTexture() && isImageIndividualAnimation() ?
std::static_pointer_cast<AnimatedTexture>(m_imageTexture)->get(m_currentFrame, m_imageAnimatorTimer) : m_imageTexture;

g_drawPool.setDrawOrder(m_imageDrawOrder);

for (const auto& [dest, src] : m_imageCoordsCache) {
if (useRepeated)
g_drawPool.addTexturedRepeatedRect(dest, texture, src, m_imageColor);
else
g_drawPool.addTexturedRect(dest, texture, src, m_imageColor);
}
g_drawPool.addTexturedCoordsBuffer(texture, m_imageCoordsCache, m_imageColor);

g_drawPool.resetDrawOrder();
}
Expand Down
6 changes: 3 additions & 3 deletions src/framework/ui/uiwidgettext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ void UIWidget::drawText(const Rect& screenCoords)
return;

// Hack to fix font rendering in atlas
if (!m_atlased && g_drawPool.getAtlas() && m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType())) {
m_atlased = true;
m_textCachedScreenCoords = {};
if (g_drawPool.getAtlas() && m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType()) != m_lastAtlasRegion) {
m_lastAtlasRegion = m_font->getTexture()->getAtlas(g_drawPool.getAtlas()->getType());
updateText();
}

if (screenCoords != m_textCachedScreenCoords) {
Expand Down
Loading