Commit b28b6492 authored by mercury233's avatar mercury233 Committed by GitHub

add config for image load background thread and multi thread (#2822)

* add gameConf.use_image_load_background_thread

* preformance

* fix config not saving

* add gameConf.use_image_scale_multi_thread

* fix default use_image_load_background_thread
parent ec24699d
...@@ -1261,12 +1261,8 @@ void Game::DrawDeckBd() { ...@@ -1261,12 +1261,8 @@ void Game::DrawDeckBd() {
driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000); driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630)); driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630));
} }
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD int max_result = mainGame->gameConf.use_image_load_background_thread ? 9 : 7;
constexpr int MAX_RESULT = 9; for(int i = 0; i < max_result && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
#else
constexpr int MAX_RESULT = 7;
#endif
for(int i = 0; i < MAX_RESULT && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()]; code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()];
if(i >= 7) if(i >= 7)
{ {
......
...@@ -1330,6 +1330,10 @@ void Game::LoadConfig() { ...@@ -1330,6 +1330,10 @@ void Game::LoadConfig() {
gameConf.use_d3d = std::strtol(valbuf, nullptr, 10) > 0; gameConf.use_d3d = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "use_image_scale")) { } else if(!std::strcmp(strbuf, "use_image_scale")) {
gameConf.use_image_scale = std::strtol(valbuf, nullptr, 10) > 0; gameConf.use_image_scale = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_scale_multi_thread")) {
gameConf.use_image_scale_multi_thread = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_load_background_thread")) {
gameConf.use_image_load_background_thread = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "errorlog")) { } else if(!std::strcmp(strbuf, "errorlog")) {
unsigned int val = std::strtol(valbuf, nullptr, 10); unsigned int val = std::strtol(valbuf, nullptr, 10);
enable_log = val & 0xff; enable_log = val & 0xff;
...@@ -1461,6 +1465,8 @@ void Game::SaveConfig() { ...@@ -1461,6 +1465,8 @@ void Game::SaveConfig() {
char linebuf[CONFIG_LINE_SIZE]; char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0); std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
std::fprintf(fp, "use_image_scale = %d\n", gameConf.use_image_scale ? 1 : 0); std::fprintf(fp, "use_image_scale = %d\n", gameConf.use_image_scale ? 1 : 0);
std::fprintf(fp, "use_image_scale_multi_thread = %d\n", gameConf.use_image_scale_multi_thread ? 1 : 0);
std::fprintf(fp, "use_image_load_background_thread = %d\n", gameConf.use_image_load_background_thread ? 1 : 0);
std::fprintf(fp, "antialias = %d\n", gameConf.antialias); std::fprintf(fp, "antialias = %d\n", gameConf.antialias);
std::fprintf(fp, "errorlog = %u\n", enable_log); std::fprintf(fp, "errorlog = %u\n", enable_log);
BufferIO::CopyWideString(ebNickName->getText(), gameConf.nickname); BufferIO::CopyWideString(ebNickName->getText(), gameConf.nickname);
......
...@@ -49,6 +49,12 @@ bool IsExtension(const char* filename, const char(&extension)[N]) { ...@@ -49,6 +49,12 @@ bool IsExtension(const char* filename, const char(&extension)[N]) {
struct Config { struct Config {
bool use_d3d{ false }; bool use_d3d{ false };
bool use_image_scale{ true }; bool use_image_scale{ true };
bool use_image_scale_multi_thread{ true };
#ifdef _OPENMP
bool use_image_load_background_thread{ false };
#else
bool use_image_load_background_thread{ true };
#endif
unsigned short antialias{ 0 }; unsigned short antialias{ 0 };
unsigned short serverport{ 7911 }; unsigned short serverport{ 7911 };
unsigned char textfontsize{ 14 }; unsigned char textfontsize{ 14 };
......
#include "image_manager.h" #include "image_manager.h"
#include "game.h" #include "game.h"
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <thread> #include <thread>
#endif
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif #endif
...@@ -22,10 +20,8 @@ bool ImageManager::Initial() { ...@@ -22,10 +20,8 @@ bool ImageManager::Initial() {
tUnknownFit = nullptr; tUnknownFit = nullptr;
tUnknownThumb = nullptr; tUnknownThumb = nullptr;
tBigPicture = nullptr; tBigPicture = nullptr;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tLoading = nullptr; tLoading = nullptr;
tThumbLoadingThreadRunning = false; tThumbLoadingThreadRunning = false;
#endif
tAct = driver->getTexture("textures/act.png"); tAct = driver->getTexture("textures/act.png");
tAttack = driver->getTexture("textures/attack.png"); tAttack = driver->getTexture("textures/attack.png");
tChain = driver->getTexture("textures/chain.png"); tChain = driver->getTexture("textures/chain.png");
...@@ -66,11 +62,7 @@ void ImageManager::ClearTexture() { ...@@ -66,11 +62,7 @@ void ImageManager::ClearTexture() {
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) { for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) {
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second && tit->second != tLoading) if(tit->second && tit->second != tLoading)
#else
if(tit->second)
#endif
driver->removeTexture(tit->second); driver->removeTexture(tit->second);
} }
if(tBigPicture != nullptr) { if(tBigPicture != nullptr) {
...@@ -80,14 +72,12 @@ void ImageManager::ClearTexture() { ...@@ -80,14 +72,12 @@ void ImageManager::ClearTexture() {
tMap[0].clear(); tMap[0].clear();
tMap[1].clear(); tMap[1].clear();
tThumb.clear(); tThumb.clear();
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tThumbLoadingMutex.lock(); tThumbLoadingMutex.lock();
tThumbLoading.clear(); tThumbLoading.clear();
while(!tThumbLoadingCodes.empty()) while(!tThumbLoadingCodes.empty())
tThumbLoadingCodes.pop(); tThumbLoadingCodes.pop();
tThumbLoadingThreadRunning = false; tThumbLoadingThreadRunning = false;
tThumbLoadingMutex.unlock(); tThumbLoadingMutex.unlock();
#endif
tFields.clear(); tFields.clear();
} }
void ImageManager::RemoveTexture(int code) { void ImageManager::RemoveTexture(int code) {
...@@ -123,10 +113,8 @@ void ImageManager::ResizeTexture() { ...@@ -123,10 +113,8 @@ void ImageManager::ResizeTexture() {
driver->removeTexture(tUnknown); driver->removeTexture(tUnknown);
driver->removeTexture(tUnknownFit); driver->removeTexture(tUnknownFit);
driver->removeTexture(tUnknownThumb); driver->removeTexture(tUnknownThumb);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
driver->removeTexture(tLoading); driver->removeTexture(tLoading);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb); tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
#endif
tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT); tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit); tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit);
tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb); tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb);
...@@ -150,7 +138,7 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) { ...@@ -150,7 +138,7 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
const double rx = (double)srcDim.Width / destDim.Width; const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height; const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel #pragma omp parallel if(mainGame->gameConf.use_image_scale_multi_thread)
{ {
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa; double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
irr::video::SColor pxl, npxl; irr::video::SColor pxl, npxl;
...@@ -298,7 +286,6 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) { ...@@ -298,7 +286,6 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) {
tBigPicture = texture; tBigPicture = texture;
return texture; return texture;
} }
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
int ImageManager::LoadThumbThread() { int ImageManager::LoadThumbThread() {
while(true) { while(true) {
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
...@@ -354,13 +341,11 @@ int ImageManager::LoadThumbThread() { ...@@ -354,13 +341,11 @@ int ImageManager::LoadThumbThread() {
imageManager.tThumbLoadingMutex.unlock(); imageManager.tThumbLoadingMutex.unlock();
return 0; return 0;
} }
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* ImageManager::GetTextureThumb(int code) { irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0) if(code == 0)
return tUnknownThumb; return tUnknownThumb;
#ifndef YGOPRO_USE_THUMB_LOAD_THREAD
auto tit = tThumb.find(code); auto tit = tThumb.find(code);
if(tit == tThumb.end()) { if(tit == tThumb.end() && !mainGame->gameConf.use_image_load_background_thread) {
char file[256]; char file[256];
std::snprintf(file, sizeof file, "expansions/pics/thumbnail/%d.jpg", code); std::snprintf(file, sizeof file, "expansions/pics/thumbnail/%d.jpg", code);
int width = CARD_THUMB_WIDTH * mainGame->xScale; int width = CARD_THUMB_WIDTH * mainGame->xScale;
...@@ -381,23 +366,24 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) { ...@@ -381,23 +366,24 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
tThumb[code] = img; tThumb[code] = img;
return (img == NULL) ? tUnknownThumb : img; return (img == NULL) ? tUnknownThumb : img;
} }
#else // YGOPRO_USE_THUMB_LOAD_THREAD if(tit == tThumb.end() || tit->second == tLoading) {
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code); auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) { if(lit != tThumbLoading.end()) {
if(lit->second != nullptr) { if(lit->second != nullptr) {
char file[256]; char file[256];
std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code); std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code);
irr::video::ITexture* texture = driver->addTexture(file, lit->second); // textures must be added in the main thread due to OpenGL irr::video::ITexture* texture = driver->addTexture(file, lit->second); // textures must be added in the main thread due to OpenGL
lit->second->drop(); lit->second->drop();
tThumb[code] = texture; tThumb[code] = texture;
} else { } else {
tThumb[code] = nullptr; tThumb[code] = nullptr;
}
tThumbLoading.erase(lit);
} }
tThumbLoading.erase(lit); imageManager.tThumbLoadingMutex.unlock();
tit = tThumb.find(code);
} }
imageManager.tThumbLoadingMutex.unlock();
auto tit = tThumb.find(code);
if(tit == tThumb.end()) { if(tit == tThumb.end()) {
tThumb[code] = tLoading; tThumb[code] = tLoading;
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
...@@ -409,7 +395,6 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) { ...@@ -409,7 +395,6 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
imageManager.tThumbLoadingMutex.unlock(); imageManager.tThumbLoadingMutex.unlock();
return tLoading; return tLoading;
} }
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second) if(tit->second)
return tit->second; return tit->second;
else else
......
#ifndef IMAGEMANAGER_H #ifndef IMAGEMANAGER_H
#define IMAGEMANAGER_H #define IMAGEMANAGER_H
#ifndef _OPENMP
#define YGOPRO_USE_THUMB_LOAD_THREAD
#endif
#include "config.h" #include "config.h"
#include "data_manager.h" #include "data_manager.h"
#include <unordered_map> #include <unordered_map>
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <queue> #include <queue>
#include <mutex> #include <mutex>
#endif
namespace ygo { namespace ygo {
...@@ -27,19 +21,15 @@ public: ...@@ -27,19 +21,15 @@ public:
irr::video::ITexture* GetBigPicture(int code, float zoom); irr::video::ITexture* GetBigPicture(int code, float zoom);
irr::video::ITexture* GetTextureThumb(int code); irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code); irr::video::ITexture* GetTextureField(int code);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
static int LoadThumbThread(); static int LoadThumbThread();
#endif
std::unordered_map<int, irr::video::ITexture*> tMap[2]; std::unordered_map<int, irr::video::ITexture*> tMap[2];
std::unordered_map<int, irr::video::ITexture*> tThumb; std::unordered_map<int, irr::video::ITexture*> tThumb;
std::unordered_map<int, irr::video::ITexture*> tFields; std::unordered_map<int, irr::video::ITexture*> tFields;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
std::unordered_map<int, irr::video::IImage*> tThumbLoading; std::unordered_map<int, irr::video::IImage*> tThumbLoading;
std::queue<int> tThumbLoadingCodes; std::queue<int> tThumbLoadingCodes;
std::mutex tThumbLoadingMutex; std::mutex tThumbLoadingMutex;
bool tThumbLoadingThreadRunning; bool tThumbLoadingThreadRunning;
#endif
irr::IrrlichtDevice* device; irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver; irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[4]; irr::video::ITexture* tCover[4];
...@@ -47,9 +37,7 @@ public: ...@@ -47,9 +37,7 @@ public:
irr::video::ITexture* tUnknownFit; irr::video::ITexture* tUnknownFit;
irr::video::ITexture* tUnknownThumb; irr::video::ITexture* tUnknownThumb;
irr::video::ITexture* tBigPicture; irr::video::ITexture* tBigPicture;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* tLoading; irr::video::ITexture* tLoading;
#endif
irr::video::ITexture* tAct; irr::video::ITexture* tAct;
irr::video::ITexture* tAttack; irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated; irr::video::ITexture* tNegated;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment