custom textures: fix race conditions

This commit is contained in:
Flyinghead 2019-04-06 19:38:00 +02:00
parent e8205e568b
commit 4b7e4f4677
5 changed files with 29 additions and 38 deletions

View File

@ -46,23 +46,28 @@ void CustomTexture::LoaderThread()
if (texture != NULL)
{
// FIXME texture may have been deleted. Need to detect this.
texture->ComputeHash();
int width, height;
u8 *image_data = LoadCustomTexture(texture->texture_hash, width, height);
if (image_data == NULL)
if (texture->custom_image_data != NULL)
{
image_data = LoadCustomTexture(texture->old_texture_hash, width, height);
delete [] texture->custom_image_data;
texture->custom_image_data = NULL;
}
if (image_data != NULL)
if (!texture->dirty)
{
if (texture->custom_image_data != NULL)
delete [] texture->custom_image_data;
texture->custom_width = width;
texture->custom_height = height;
texture->custom_image_data = image_data;
int width, height;
u8 *image_data = LoadCustomTexture(texture->texture_hash, width, height);
if (image_data == NULL)
{
image_data = LoadCustomTexture(texture->old_texture_hash, width, height);
}
if (image_data != NULL)
{
texture->custom_width = width;
texture->custom_height = height;
texture->custom_image_data = image_data;
}
}
texture->custom_load_in_progress = false;
texture->custom_load_in_progress--;
}
} while (texture != NULL);
@ -140,10 +145,9 @@ u8* CustomTexture::LoadCustomTexture(u32 hash, int& width, int& height)
void CustomTexture::LoadCustomTextureAsync(TextureCacheData *texture_data)
{
if (!Init())
{
texture_data->custom_load_in_progress = false;
return;
}
texture_data->custom_load_in_progress++;
work_queue_mutex.Lock();
work_queue.insert(work_queue.begin(), texture_data);
work_queue_mutex.Unlock();

View File

@ -53,7 +53,7 @@ private:
cThread loader_thread;
#endif
cResetEvent wakeup_thread;
std::vector<struct TextureCacheData *> work_queue;
std::vector<TextureCacheData *> work_queue;
cMutex work_queue_mutex;
};

View File

@ -1838,9 +1838,6 @@ bool RenderFrame()
glBufferData(GL_ARRAY_BUFFER,pvrrc.modtrig.bytes(),pvrrc.modtrig.head(),GL_STREAM_DRAW); glCheck();
}
int offs_x=ds2s_offs_x+0.5f;
//this needs to be scaled
//not all scaling affects pixel operations, scale to adjust for that
scale_x *= scissoring_scale_x;

View File

@ -1,5 +1,6 @@
#pragma once
#include <unordered_map>
#include <atomic>
#include "rend/rend.h"
#if (defined(GLES) && !defined(TARGET_NACL32) && HOST_OS != OS_DARWIN && !defined(USE_SDL)) || defined(_ANDROID)
@ -271,10 +272,10 @@ struct TextureCacheData
//a texture can't be both VQ and PAL at the same time
u32 texture_hash; // xxhash of texture data, used for custom textures
u32 old_texture_hash; // legacy hash
u8* custom_image_data; // loaded custom image data
u32 custom_width;
u32 custom_height;
bool custom_load_in_progress;
u8* volatile custom_image_data; // loaded custom image data
volatile u32 custom_width;
volatile u32 custom_height;
std::atomic_int custom_load_in_progress;
void PrintTextureName();

View File

@ -296,10 +296,7 @@ void TextureCacheData::Update()
}
}
if (settings.rend.CustomTextures)
{
custom_load_in_progress = true;
custom_texture.LoadCustomTextureAsync(this);
}
void *temp_tex_buffer = NULL;
u32 upscaled_w = w;
@ -428,7 +425,7 @@ void TextureCacheData::UploadToGPU(GLuint textype, int width, int height, u8 *te
void TextureCacheData::CheckCustomTexture()
{
if (custom_image_data != NULL)
if (custom_load_in_progress == 0 && custom_image_data != NULL)
{
UploadToGPU(GL_UNSIGNED_BYTE, custom_width, custom_height, custom_image_data);
delete [] custom_image_data;
@ -446,7 +443,7 @@ bool TextureCacheData::NeedsUpdate() {
bool TextureCacheData::Delete()
{
if (custom_load_in_progress)
if (custom_load_in_progress > 0)
return false;
if (pData) {
@ -736,11 +733,7 @@ TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw) {
}
else //create if not existing
{
TextureCacheData tfc={0};
TexCache[key] = tfc;
tx=TexCache.find(key);
tf=&tx->second;
tf=&TexCache[key];
tf->tsp = tsp;
tf->tcw = tcw;
@ -800,11 +793,7 @@ text_info raw_GetTexture(TSP tsp, TCW tcw)
}
else //create if not existing
{
TextureCacheData tfc = { 0 };
TexCache[key] = tfc;
tx = TexCache.find(key);
tf = &tx->second;
tf = &TexCache[key];
tf->tsp = tsp;
tf->tcw = tcw;