Add async texture loading
This commit is contained in:
+17
-3
@@ -180,11 +180,11 @@ errorret_t assetUpdate(void) {
|
|||||||
// If an error occured these things need to be true, basically just
|
// If an error occured these things need to be true, basically just
|
||||||
// ensuring the sync loader is setting the error correctly.
|
// ensuring the sync loader is setting the error correctly.
|
||||||
if(errorIsNotOk(ret)) {
|
if(errorIsNotOk(ret)) {
|
||||||
|
errorCatch(errorPrint(ret));
|
||||||
assertTrue(
|
assertTrue(
|
||||||
loading->entry->state == ASSET_ENTRY_STATE_ERROR,
|
loading->entry->state == ASSET_ENTRY_STATE_ERROR,
|
||||||
"Loader did not set entry state to error on failed load."
|
"Loader did not set entry state to error on failed load."
|
||||||
);
|
);
|
||||||
errorCatch(errorPrint(ret));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
threadMutexUnlock(&loading->mutex);
|
threadMutexUnlock(&loading->mutex);
|
||||||
@@ -236,8 +236,22 @@ void assetUpdateAsync(thread_t *thread) {
|
|||||||
switch(loading->entry->state) {
|
switch(loading->entry->state) {
|
||||||
case ASSET_ENTRY_STATE_PENDING_ASYNC:
|
case ASSET_ENTRY_STATE_PENDING_ASYNC:
|
||||||
loading->entry->state = ASSET_ENTRY_STATE_LOADING_ASYNC;
|
loading->entry->state = ASSET_ENTRY_STATE_LOADING_ASYNC;
|
||||||
printf("Simulated async load\n");
|
assertNotNull(
|
||||||
sleep(1);
|
ASSET_LOADER_CALLBACKS[loading->type].loadAsync,
|
||||||
|
"Loader does not support async loading."
|
||||||
|
);
|
||||||
|
errorret_t ret = (
|
||||||
|
ASSET_LOADER_CALLBACKS[loading->type].loadAsync(loading)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(errorIsNotOk(ret)) {
|
||||||
|
errorCatch(errorPrint(ret));
|
||||||
|
assertTrue(
|
||||||
|
loading->entry->state == ASSET_ENTRY_STATE_ERROR,
|
||||||
|
"Loader did not set entry state to error on failed load."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
threadMutexUnlock(&loading->mutex);
|
threadMutexUnlock(&loading->mutex);
|
||||||
loading++;
|
loading++;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,26 +12,31 @@ assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
|
|||||||
|
|
||||||
[ASSET_LOADER_TYPE_MESH] = {
|
[ASSET_LOADER_TYPE_MESH] = {
|
||||||
.loadSync = assetMeshLoaderSync,
|
.loadSync = assetMeshLoaderSync,
|
||||||
|
.loadAsync = NULL,
|
||||||
.dispose = assetMeshDispose
|
.dispose = assetMeshDispose
|
||||||
},
|
},
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TEXTURE] = {
|
[ASSET_LOADER_TYPE_TEXTURE] = {
|
||||||
.loadSync = assetTextureLoaderSync,
|
.loadSync = assetTextureLoaderSync,
|
||||||
|
.loadAsync = assetTextureLoaderAsync,
|
||||||
.dispose = assetTextureDispose
|
.dispose = assetTextureDispose
|
||||||
},
|
},
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TILESET] = {
|
[ASSET_LOADER_TYPE_TILESET] = {
|
||||||
.loadSync = assetTilesetLoaderSync,
|
.loadSync = assetTilesetLoaderSync,
|
||||||
|
.loadAsync = NULL,
|
||||||
.dispose = assetTilesetDispose
|
.dispose = assetTilesetDispose
|
||||||
},
|
},
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_LOCALE] = {
|
[ASSET_LOADER_TYPE_LOCALE] = {
|
||||||
.loadSync = assetLocaleLoaderSync,
|
.loadSync = assetLocaleLoaderSync,
|
||||||
|
.loadAsync = NULL,
|
||||||
.dispose = assetLocaleDispose
|
.dispose = assetLocaleDispose
|
||||||
},
|
},
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_JSON] = {
|
[ASSET_LOADER_TYPE_JSON] = {
|
||||||
.loadSync = assetJsonLoaderSync,
|
.loadSync = assetJsonLoaderSync,
|
||||||
|
.loadAsync = NULL,
|
||||||
.dispose = assetJsonDispose
|
.dispose = assetJsonDispose
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,10 +52,12 @@ typedef struct assetloading_s assetloading_t;
|
|||||||
typedef struct assetentry_s assetentry_t;
|
typedef struct assetentry_s assetentry_t;
|
||||||
|
|
||||||
typedef errorret_t (assetloadersynccallback_t)(assetloading_t *loading);
|
typedef errorret_t (assetloadersynccallback_t)(assetloading_t *loading);
|
||||||
|
typedef errorret_t (assetloaderasynccallback_t)(assetloading_t *loading);
|
||||||
typedef errorret_t (assetloaderdisposecallback_t)(assetentry_t *entry);
|
typedef errorret_t (assetloaderdisposecallback_t)(assetentry_t *entry);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
assetloadersynccallback_t *loadSync;
|
assetloadersynccallback_t *loadSync;
|
||||||
|
assetloaderasynccallback_t *loadAsync;
|
||||||
assetloaderdisposecallback_t *dispose;
|
assetloaderdisposecallback_t *dispose;
|
||||||
} assetloadercallbacks_t;
|
} assetloadercallbacks_t;
|
||||||
|
|
||||||
|
|||||||
@@ -52,10 +52,19 @@ int assetTextureEOF(void *user) {
|
|||||||
return file->position >= file->size;
|
return file->position >= file->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
errorret_t assetTextureLoaderAsync(assetloading_t *loading) {
|
||||||
assertNotNull(loading, "Loading cannot be NULL");
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
|
|
||||||
|
// Only care about loading pixels.
|
||||||
|
if(loading->loading.texture.state != ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS){
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
// Init the file
|
// Init the file
|
||||||
|
assertNull(
|
||||||
|
loading->loading.texture.data, "Pixels already defined?"
|
||||||
|
);
|
||||||
|
|
||||||
assetfile_t *file = &loading->loading.texture.file;
|
assetfile_t *file = &loading->loading.texture.file;
|
||||||
assetLoaderErrorChain(loading, assetFileInit(
|
assetLoaderErrorChain(loading, assetFileInit(
|
||||||
file,
|
file,
|
||||||
@@ -77,13 +86,12 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load image pixels.
|
// Load image pixels.
|
||||||
int width, height, channels;
|
|
||||||
loading->loading.texture.data = stbi_load_from_callbacks(
|
loading->loading.texture.data = stbi_load_from_callbacks(
|
||||||
&ASSET_TEXTURE_STB_CALLBACKS,
|
&ASSET_TEXTURE_STB_CALLBACKS,
|
||||||
file,
|
file,
|
||||||
&width,
|
&loading->loading.texture.width,
|
||||||
&height,
|
&loading->loading.texture.height,
|
||||||
&channels,
|
&loading->loading.texture.channels,
|
||||||
channelsDesired
|
channelsDesired
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -101,14 +109,43 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
|||||||
if(!isHostLittleEndian()) {
|
if(!isHostLittleEndian()) {
|
||||||
stbi__vertical_flip(
|
stbi__vertical_flip(
|
||||||
loading->loading.texture.data,
|
loading->loading.texture.data,
|
||||||
width, height, channelsDesired
|
loading->loading.texture.width,
|
||||||
|
loading->loading.texture.height,
|
||||||
|
loading->loading.texture.channels
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE;
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_SYNC;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||||
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
|
|
||||||
|
switch(loading->loading.texture.state) {
|
||||||
|
case ASSET_TEXTURE_LOADING_STATE_INITIAL:
|
||||||
|
loading->loading.texture.state = ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS;
|
||||||
|
loading->entry->state = ASSET_ENTRY_STATE_PENDING_ASYNC;
|
||||||
|
errorOk();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
// Create the texture.
|
// Create the texture.
|
||||||
|
assertNotNull(
|
||||||
|
loading->loading.texture.data, "Pixels should have been loaded by now."
|
||||||
|
);
|
||||||
|
|
||||||
assetLoaderErrorChain(loading, textureInit(
|
assetLoaderErrorChain(loading, textureInit(
|
||||||
(texture_t*)&loading->entry->data.texture,
|
(texture_t*)&loading->entry->data.texture,
|
||||||
(int32_t)width, (int32_t)height,
|
loading->loading.texture.width,
|
||||||
|
loading->loading.texture.height,
|
||||||
loading->entry->input->texture,
|
loading->entry->input->texture,
|
||||||
(texturedata_t){
|
(texturedata_t){
|
||||||
.rgbaColors = (color_t*)loading->loading.texture.data
|
.rgbaColors = (color_t*)loading->loading.texture.data
|
||||||
|
|||||||
@@ -13,8 +13,18 @@ typedef struct assetloading_s assetloading_t;
|
|||||||
typedef struct assetentry_s assetentry_t;
|
typedef struct assetentry_s assetentry_t;
|
||||||
typedef textureformat_t assettextureloaderinput_t;
|
typedef textureformat_t assettextureloaderinput_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ASSET_TEXTURE_LOADING_STATE_INITIAL,
|
||||||
|
ASSET_TEXTURE_LOADING_STATE_LOAD_PIXELS,
|
||||||
|
ASSET_TEXTURE_LOADING_STATE_CREATE_TEXTURE,
|
||||||
|
ASSET_TEXTURE_LOADING_STATE_DONE
|
||||||
|
} assettextureloadingstate_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
assetfile_t file;
|
assetfile_t file;
|
||||||
|
assettextureloadingstate_t state;
|
||||||
|
|
||||||
|
int channels, width, height;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} assettextureloaderloading_t;
|
} assettextureloaderloading_t;
|
||||||
|
|
||||||
@@ -46,6 +56,14 @@ void assetTextureSkipper(void *user, int n);
|
|||||||
*/
|
*/
|
||||||
int assetTextureEOF(void *user);
|
int assetTextureEOF(void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronous loader for texture assets.
|
||||||
|
*
|
||||||
|
* @param loading Loading information for the asset being loaded.
|
||||||
|
* @return Error code indicating success or failure of the load operation.
|
||||||
|
*/
|
||||||
|
errorret_t assetTextureLoaderAsync(assetloading_t *loading);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronous loader for texture assets.
|
* Synchronous loader for texture assets.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user