mirror of
https://github.com/libretro/parallel-dc.git
synced 2026-11-08 17:27:41 -10:00
Whether a game has custom textures was a plain bool that the loader thread wrote once it had listed the directory and the renderer read; and nothing cleared it when the game went. After a game with a texture pack, one without inherited "available": its textures were queued for a loader that had not been started, and a texture waiting on the loader cannot be freed. The same if the loader thread could not be started. It is an atomic now, cleared (with the path) when the game goes, and cleared again if the thread does not start. Not in this: the loader still works out a texture's hash itself, from video memory the game may be writing. That is its own change.
70 lines
2.3 KiB
C++
70 lines
2.3 KiB
C++
/*
|
|
Copyright 2018 flyinghead
|
|
|
|
This file is part of reicast.
|
|
|
|
reicast is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
reicast is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
|
|
#include "TexCache.h"
|
|
#include "stdclass.h"
|
|
#include "lockfree.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
class CustomTexture {
|
|
public:
|
|
CustomTexture() : loader_thread(loader_thread_func, this)
|
|
{
|
|
retro_atomic_int_init(&initialized, 0);
|
|
retro_atomic_int_init(&custom_textures_available, 0);
|
|
}
|
|
~CustomTexture() { Terminate(); }
|
|
u8* LoadCustomTexture(u32 hash, int& width, int& height);
|
|
void LoadCustomTextureAsync(BaseTextureCacheData *texture_data);
|
|
void DumpTexture(u32 hash, int w, int h, TextureType textype, void *src_buffer);
|
|
void Terminate();
|
|
|
|
private:
|
|
bool Init();
|
|
void LoaderThread();
|
|
u8* LoadPNG(const std::string& fname, int &width, int &height);
|
|
std::string GetGameId();
|
|
void LoadMap();
|
|
|
|
static void *loader_thread_func(void *param) { ((CustomTexture *)param)->LoaderThread(); return NULL; }
|
|
|
|
void Load(BaseTextureCacheData *texture);
|
|
|
|
retro_atomic_int_t initialized;
|
|
/* Set by Init() for the directory being there, and by the loader once
|
|
* it has listed it (to whether anything usable was in it); read by the
|
|
* renderer. Cleared when the game goes. */
|
|
retro_atomic_int_t custom_textures_available;
|
|
std::string textures_path;
|
|
cThread loader_thread;
|
|
cResetEvent wakeup_thread;
|
|
/* Textures waiting for the loader thread. A texture is on the list at
|
|
* most once: it is pushed when its custom_load_in_progress count leaves
|
|
* zero, and the loader only lets the count return to zero once it is
|
|
* done with the texture. */
|
|
cMpscList<BaseTextureCacheData, &BaseTextureCacheData::custom_load_next> work_queue;
|
|
std::map<u32, std::string> texture_map;
|
|
};
|
|
|
|
extern CustomTexture custom_texture;
|