Resuming on my threading support work with the card caching mechanism. This change unfortunately touches quite a few files, but I needed to get it out of the way before things got out of hand: one significant hurdle is the assumed lifetime of a JQuad pointer. In a single threaded model, the life time of the pointer is clear: you fetch it into the cache, the cache makes room, you use the pointer immediately. In a multithreaded context however, it's unsafe, as the drawing thread can request a few JQuads, and the cache operating on a separate thread can potentially bounce a JQuad out of the cache before the draw routine is done using it, which ends up in an access violation when you attempt to draw using an invalidated quad pointer. To prevent this, the bulk of this change swaps out the use of naked JQuad* pointers in the code with a JQuadPtr, which is basically a typedef to a boost shared_ptr<JQuad>.

This btw points out another circular dependancy between the texture and the JQuad - a texture owns a bunch of JQuads, yet the renderer uses JQuads and always assumes that the texture is valid.  We're going to need to add more defensiveness to JGE to protect against this.

Other changes in this check-in:  WResourceManager doesn't derive from JResourceManager anymore.  It actually didn't require anything from the base, so I killed the dependency.  Also cleaned up the notion of a WTrackedQuad in the WCachedResource - it didn't need a separate class, just a better container.

I've build this & tested against PSP, win, linux, QT (linux).  I haven't tried against iOS and QT Win, or Maemo.  If these other platforms are broken, I apologize in advance! - I'm hoping it should be fairly simple to put them back into play.
This commit is contained in:
wrenczes@gmail.com
2011-02-01 10:37:21 +00:00
parent 0b2f83c499
commit 76cba56a1c
51 changed files with 783 additions and 1025 deletions

View File

@@ -5,12 +5,13 @@
#include <JTypes.h>
#include "MTGDeck.h"
#include "MTGCard.h"
#include "utils.h"
#include "WCachedResource.h"
#include "WFont.h"
#define HUGE_CACHE_LIMIT 20000000 // Size of the cache for Windows and Linux
#define SAMPLES_CACHE_SIZE 1500000 // Size in bytes of the cached samples
#define PSI_CACHE_SIZE 500000 // Size in bytes of the cahed particles
#define PSI_CACHE_SIZE 500000 // Size in bytes of the cached particles
#define TEXTURES_CACHE_MINSIZE 2000000 // Minimum size of the cache on the PSP. The program should complain if the cache ever gets smaller than this
#define OPERATIONAL_SIZE 5000000 // Size required by Wagic for operational stuff. 3MB is not enough. The cache will usually try to take (Total Ram - Operational size)
#define MIN_LINEAR_RAM 1500000
@@ -20,6 +21,7 @@
#define MAX_CACHE_TIME 2000000000
#endif
#define THUMBNAILS_OFFSET 100000000
#define OTHERS_OFFSET 2000000000
@@ -30,41 +32,39 @@
#define MAX_CACHED_SAMPLES 50
#define MAX_CACHE_GARBAGE 10
enum ENUM_WRES_INFO
{
WRES_UNLOCKED = 0, //Resource is unlocked.
WRES_MAX_LOCK = 250, //Maximum number of locks for a resource.
WRES_PERMANENT = 251, //Resource is permanent (ie, managed)
WRES_UNDERLOCKED = 252,
//Resource was released too many times.
WRES_UNLOCKED = 0, //Resource is unlocked.
WRES_MAX_LOCK = 250, //Maximum number of locks for a resource.
WRES_PERMANENT = 251, //Resource is permanent (ie, managed)
WRES_UNDERLOCKED = 252, //Resource was released too many times.
};
enum ENUM_RETRIEVE_STYLE
{
RETRIEVE_EXISTING, //Only returns a resource if it already exists. Does not lock or unlock.
RETRIEVE_NORMAL, //Returns or creates a resource. Does not change lock status.
RETRIEVE_LOCK, //As above, locks cached resource. Not for quads.
RETRIEVE_UNLOCK, //As above, unlocks cached resource. Not for quads.
RETRIEVE_RESOURCE, //Only retrieves a managed resource. Does not make a new one.
RETRIEVE_MANAGE, //Makes resource permanent.
RETRIEVE_THUMB, //Retrieve it as a thumbnail.
CACHE_THUMB = RETRIEVE_THUMB,
//Backwords compatibility.
RETRIEVE_EXISTING, //Only returns a resource if it already exists. Does not lock or unlock.
RETRIEVE_NORMAL, //Returns or creates a resource. Does not change lock status.
RETRIEVE_LOCK, //As above, locks cached resource. Not for quads.
RETRIEVE_UNLOCK, //As above, unlocks cached resource. Not for quads.
RETRIEVE_RESOURCE, //Only retrieves a managed resource. Does not make a new one.
RETRIEVE_MANAGE, //Makes resource permanent.
RETRIEVE_THUMB, //Retrieve it as a thumbnail.
CACHE_THUMB = RETRIEVE_THUMB, //Backwards compatibility.
};
enum ENUM_CACHE_SUBTYPE
{
CACHE_NORMAL = (1 << 0), //Use default values. Not really a flag.
CACHE_EXISTING = (1 << 1), //Retrieve it only if it already exists
CACHE_NORMAL = (1<<0), //Use default values. Not really a flag.
CACHE_EXISTING = (1<<1), //Retrieve it only if it already exists
//Because these bits only modify how a cached resource's Attempt() is called,
//We can use them over and over for each resource type.
TEXTURE_SUB_EXACT = (1 << 2), //Don't do any fiddling with the filename.
TEXTURE_SUB_CARD = (1 << 3), //Retrieve using cardFile, not graphicsFile.
TEXTURE_SUB_AVATAR = (1 << 4), //Retrieve using avatarFile, not graphicsFile.
TEXTURE_SUB_THUMB = (1 << 5),//Retrieve prepending "thumbnails\" to the filename.
TEXTURE_SUB_5551 = (1 << 6),
//For textures. If we have to allocate, use RGBA5551.
TEXTURE_SUB_EXACT = (1<<2), //Don't do any fiddling with the filename.
TEXTURE_SUB_CARD = (1<<3), //Retrieve using cardFile, not graphicsFile.
TEXTURE_SUB_AVATAR = (1<<4), //Retrieve using avatarFile, not graphicsFile.
TEXTURE_SUB_THUMB = (1<<5), //Retrieve prepending "thumbnails\" to the filename.
TEXTURE_SUB_5551 = (1<<6), //For textures. If we have to allocate, use RGBA5551.
};
@@ -73,8 +73,8 @@ enum ENUM_CACHE_ERROR
CACHE_ERROR_NONE = 0,
CACHE_ERROR_NOT_CACHED = CACHE_ERROR_NONE,
CACHE_ERROR_404,
CACHE_ERROR_BAD, //Something went wrong with item->attempt()
CACHE_ERROR_BAD_ALLOC, //Couldn't allocate item
CACHE_ERROR_BAD, //Something went wrong with item->attempt()
CACHE_ERROR_BAD_ALLOC, //Couldn't allocate item
CACHE_ERROR_LOST,
CACHE_ERROR_NOT_MANAGED,
};
@@ -84,7 +84,7 @@ struct WCacheSort
bool operator()(const WResource * l, const WResource * r); //Predicate for use in sorting. See flatten().
};
template<class cacheItem, class cacheActual>
template <class cacheItem, class cacheActual>
class WCache
{
public:
@@ -93,13 +93,13 @@ public:
WCache();
~WCache();
cacheItem* Retrieve(int id, const string& filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Primary interface function.
cacheItem* Retrieve(int id, const string& filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); //Primary interface function.
bool Release(cacheActual* actual); //Releases an item, and deletes it if unlocked.
bool RemoveMiss(int id = 0); //Removes a cache miss.
bool RemoveOldest(); //Remove oldest unlocked item.
bool Cleanup(); //Repeats RemoveOldest() until cache fits in size limits
void ClearUnlocked(); //Remove all unlocked items.
void Refresh(); //Refreshes all cache items.
bool RemoveMiss(int id=0); //Removes a cache miss.
bool RemoveOldest(); //Remove oldest unlocked item.
bool Cleanup(); //Repeats RemoveOldest() until cache fits in size limits
void ClearUnlocked(); //Remove all unlocked items.
void Refresh(); //Refreshes all cache items.
unsigned int Flatten(); //Ensures that the times don't loop. Returns new lastTime.
void Resize(unsigned long size, int items); //Sets new limits, then enforces them. Lock safe, so not a "hard limit".
protected:
@@ -127,12 +127,11 @@ protected:
struct WManagedQuad
{
WCachedTexture * texture;
WCachedTexture* texture;
string resname;
};
//This class is a wrapper for JResourceManager
class WResourceManager: public JResourceManager
class WResourceManager
{
public:
static WResourceManager* Instance()
@@ -154,11 +153,11 @@ public:
virtual ~WResourceManager();
void Unmiss(string filename);
JQuad * RetrieveCard(MTGCard * card, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL);
JQuadPtr RetrieveCard(MTGCard * card, int style = RETRIEVE_NORMAL,int submode = CACHE_NORMAL);
JSample * RetrieveSample(const string& filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL);
JTexture * RetrieveTexture(const string& filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL);
JQuad * RetrieveQuad(const string& filename, float offX = 0.0f, float offY = 0.0f, float width = 0.0f, float height = 0.0f, string resname = "", int style = RETRIEVE_LOCK, int submode = CACHE_NORMAL, int id = 0);
JQuad * RetrieveTempQuad(const string& filename, int submode = CACHE_NORMAL);
JQuadPtr RetrieveQuad(const string& filename, float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f, string resname="", int style = RETRIEVE_LOCK, int submode = CACHE_NORMAL, int id = 0);
JQuadPtr RetrieveTempQuad(const string& filename, int submode = CACHE_NORMAL);
hgeParticleSystemInfo * RetrievePSI(const string& filename, JQuad * texture, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL);
int RetrieveError();
@@ -166,9 +165,8 @@ public:
void Release(JSample * sample);
bool RemoveOldest();
bool Cleanup(); //Force a cleanup. Return false if nothing removed.
void ClearUnlocked(); //Remove unlocked items.
void Refresh(); //Refreshes all files in cache, for when mode/profile changes.
void Refresh(); //Refreshes all files in cache, for when mode/profile changes.
unsigned int nowTime();
@@ -181,8 +179,8 @@ public:
unsigned int CountManaged();
int CreateQuad(const string &quadName, const string &textureName, float x, float y, float width, float height);
JQuad* GetQuad(const string &quadName);
JQuad* GetQuad(int id);
JQuadPtr GetQuad(const string &quadName);
JQuadPtr GetQuad(int id);
int AddQuadToManaged(const WManagedQuad& inManagedQuad);
@@ -222,17 +220,17 @@ public:
private:
/*
** Singleton object only accessibly via Instance(), constructor is private
*/
** Singleton object only accessibly via Instance(), constructor is private
*/
WResourceManager();
bool bThemedCards; //Does the theme have a "sets" directory for overwriting cards?
void FlattenTimes(); //To prevent bad cache timing on int overflow
bool bThemedCards; //Does the theme have a "sets" directory for overwriting cards?
void FlattenTimes(); //To prevent bad cache timing on int overflow
//For cached stuff
WCache<WCachedTexture, JTexture> textureWCache;
WCache<WCachedSample, JSample> sampleWCache;
WCache<WCachedParticles, hgeParticleSystemInfo> psiWCache;
WCache<WCachedTexture,JTexture> textureWCache;
WCache<WCachedSample,JSample> sampleWCache;
WCache<WCachedParticles,hgeParticleSystemInfo> psiWCache;
typedef std::map<std::string, WManagedQuad> ManagedQuadMap;
ManagedQuadMap mManagedQuads;