Asynchronous Resource Loading

edited October 2014 in General discussions
Now that the resource loading is asynchronous, I would like to add a loading screen for resources, and a progress bar.

As mentioned here: http://www.orxproject.org/forum?func=view&catid=16&id=6946#6969 I can query the resource module to know when a resource is loaded.

Is it possible to turn off async loading so that I can update the progress bar after each orxObject_CreateFromConfig statement, or is it better practice to subscribe to the:

orxRESOURCE_EVENT

and listen for a

orxRESOURCE_EVENT_ADD

and update the progress bar that way.

I could update the count of objects I expect to load and clear away the loader screen when that count is reached.

Just wanted to check that as best practice before I start.

Comments

  • edited October 2014
    Ah that's a good question.

    For starter, only textures and sounds are loaded asynchronously by orx (though you can load your own extra resources asynchronously if you have any).

    Secondly, orxRESOURCE_EVENT_ADD is not what you want. It's an event used by the resource watcher in order to support hot reload. You should deactivate it when releasing your game as resource won't change on disk anymore.

    Now for you progress bar issue, turning async loading off is probably not the best answer, as your main loop will be blocked by disk access all the time, resulting in a very choppy framerate.

    As a side note, you can't prevent sounds from being loaded asynchronously, however you can ask textures to be loaded synchronously by removing the temporary texture (orxDisplay_SetTempBitmap). Also it's good to know that sounds are processed on their own separate thread, they don't use the resource thread.

    Which brings us to the options available to you:

    - You could count how many textures you'd need to load and then listen to the orxTEXTURE_EVENT_LOAD, when both numbers match, texture loading is over. I don't think it's the easiest way to do it though.

    - You could create all objects at once (I usually have them all in a single hierarchy whose root I often call "Scene"). When the call to create all those objects is done, you can now easily setup your progress bar as you can poll how many pending resource operations are left by calling orxResource_GetTotalPendingOpCounter(). When this counter reaches 0, you're done loading.

    To sum it up, here's how I'd do it:

    - Create your loading screen/progress bar, this way resource will be handled first for them
    - call orxObject_CreateFromConfig("Scene")
    - call orxResource_GetTotalOpCounter(), match that number with your whole progress bar, ie. if you have X operations pending at that moment, everytime one operation is processed, your bar progresses by 1/Xth.
    - Every update call orxResource_GetTotalOpCounter(), update your progress bar accordingly. When reaching 0, delete the loading screen and continue on your merry way. :)

    Lemme know if you see any obvious issue with this approach.
  • edited October 2014
    Fantastic, thanks Iarwain. Completely what I needed. Screens and progress bar methods are done and working, I just need to do what described and it should be finished this evening.
  • edited October 2014
    Confirming all went well. Hooking up the texture loading event is very straight forward.
  • edited February 2015
    Hi, forgive me for resurrecting this thread, but it's about exactly what I need, but it doesn't work for me;

    iarwain wrote:
    - You could create all objects at once (I usually have them all in a single hierarchy whose root I often call "Scene"). When the call to create all those objects is done, you can now easily setup your progress bar as you can poll how many pending resource operations are left by calling orxResource_GetTotalPendingOpCounter(). When this counter reaches 0, you're done loading.

    This sounds like a very nice solution, but it doesn't work well (under orx-1.6). I've tried to start with a very simple loading screen, that just says "Loading..." until all the assets are loaded. I did this by having an initial camera whose GroupList contains only the loading screen objects (the "Loading..." text), then I've created my scene as usual. Then in my run callback, I query the orxResource_GetTotalPendingOpCounter, and switch to my main camera when it returns 0. The trouble is that this happens too soon.

    When I switch to the main camera, I can still see that the background texture is missing for a brief second. In order to make it more visible, I've tried using a very large texture that takes 3-4 seconds to load, and I can clearly see that the loading screen exits too soon. In order to make sure that I'm not making a mistake while preloading the scene, I've instead tried to keep the loading screen by waiting for 5 seconds (instead of waiting for the orxResource_GetTotalPendingOpCounter). In this case, there was no brief white background, so the loading does take place while the loading screen is displayed.

    Here's the sequence I follow:
    orxViewport_SetCamera(viewPort,LoadingCamera))
    orxObject_CreateFromConfig("LoadingScene");
    orxObject_CreateFromConfig("GameScene");
    Enter Loading State
    
    Loading State:
       if(orxResource_GetTotalPendingOpCounter()==0) {
           orxViewport_SetCamera(viewPort,MainCamera));
           Enter Playing State
       }
    

    I've checked the source code of Raster Blaster Pinball to see how Sausage ended up doing it, and it seems that he's ended up counting the number of texture load events and comparing the number to a predefined constant. I wish there were a more automated way (including sounds) to do this. Iarwain's recommendation does seem to be the perfect solution, but orxResource_GetTotalPendingOpCounter doesn't return the right thing. Maybe it returns the number of operations that hasn't started yet? There's something clearly wrong because I can see that orxResource_GetTotalPendingOpCounter returns 0 within 20ms or so...

    By the way, it's easy to preload textures without showing them, but what's your suggestion about doing the same for sounds? Should I play dummy sounds whose volume is 0? Or is there a better way?

    Thanks
  • edited February 2015
    Currently the function reports only the pending operation, ie. the actual disk accesses that are not finished, but doesn't take into account operations that have not yet been notified back to the caller, however I just changed that locally and will commit in a few minutes.

    Let me know if that fixes your issue. If not, if you could have a small setup for me to investigate, that would be appreciated. :)

    Regarding the sounds, what I usually do (it only works for sounds that have the config property KeepInCache set to true), is that I create them and delete them right away: the samples will get loaded but never played. I usually do this at the orxOBJECT level. One can even simply set dummies with a lifetime of 0, something like this (though I haven't tried it myself):
    [O-MySound]
    SoundList = 
    
    [O-MySoundPreload@O-MySound]
    LifeTime = 0
    
  • edited February 2015
    enobayram wrote:
    I've checked the source code of Raster Blaster Pinball to see how Sausage ended up doing it

    Actually check Bean Farmer Pinball code instead. Raster Blaster will be changed.

    Interested to see what happens here because I think my routine is still flawed. In the case of Android (and only Android), sometimes the game load freezes at ~95%. All other versions are fine.

    Seeing what Iarwain wrote, I have some patching to do with loading on Android.
  • edited February 2015
    iarwain wrote:
    Currently the function reports only the pending operation, ie. the actual disk accesses that are not finished, but doesn't take into account operations that have not yet been notified back to the caller, however I just changed that locally and will commit in a few minutes.
    I think the time spent accessing the disk is a fraction of the time it takes to load a texture, the costly part seems to be decoding the compressed image.
    Let me know if that fixes your issue. If not, if you could have a small setup for me to investigate, that would be appreciated. :)
    I've just tried with the linux64 2015-02-24 nightly build, and the problem persists. I've attached a minimal setup, which tries to preload a large background image with a loading screen. You can see that there's a significant gap between the "loading..." text disappearing and the actual background texture appearing.
    Regarding the sounds...
    That's quite convenient, thanks :)

    sausage wrote:
    Actually check Bean Farmer Pinball code instead. Raster Blaster will be changed.
    Thanks, I'll check it as soon as I find some time :) https://forum.orx-project.org/uploads/legacy/fbfiles/files/loading_question.zip
  • edited February 2015
    I think the time spent accessing the disk is a fraction of the time it takes to load a texture, the costly part seems to be decoding the compressed image.

    I was afraid of that, and now that you confirmed it, we'll need to find a way to work around, beside listening to all texture load events. :)

    One option would be to have a "start" texture load event, this way it'd be easy to know how many are pending without knowing how many textures are handled. I like this one, because it's an easy one. ;)

    Unfortunately the decompression is handled on a separate thread, via the task system, but there isn't any good query API yet, all that is available is orxThread_GetTaskCounter(), which won't filter out on task types. So I guess another option would be to add types to tasks and a way to filter them out on queries. I like it a bit less because it's more work for a rather independent problem, in the end. ;)

    What do you think?

    PS: Thanks for the testbed, I'll use it to test whichever solution gets implemented.
  • edited February 2015
    Ok so sounds like we need to come up with a clever routine by listening to both texture start and loaded events.

    My next version of the game loader was going to increment a texturesToLoad ((int)) variable on every start event, and then decrement on every loaded event.

    That way I would guarentee the numbers match dynamically.

    My only concern was the possibility that 5 start events could fire, and 5 loaded events could fire before any more starts which means that the loader would think it was finished.

    Might need a delay at the end of the routine just in case to test for any further start events.

    I'll write it and try it out. This doesn't address the decompression issue, but perhaps the forced delay does for now.
  • edited February 2015
    The load event are sent after the decompression + upload was done.
    As for a delayed check, that should be rather straightforward to do with a simple orxClock_AddGlobalTimer(), if need be.

    Another option would be to wait for a custom event (or input, they're handy for this as well) that the user would fire when he knows that all the texture loads have been queued. Only then will the test wait for the load counter to go back to 0.

    I guess I could also manage a pending load counter directly inside the display plugin (or the texture module), which would simplify one's work on the client side.
  • edited February 2015
    iarwain wrote:
    The load event are sent after the decompression + upload was done.

    Are you saying that the orxTEXTURE_EVENT_LOAD doesn't fire until the file load and decompression of the texture is totally complete? Is that's the case, then I probably have everything I need to solve my particular case.

    Unless I'm overlooking something.
  • edited February 2015
    It would be also handy if there could be the method for querying the status of resource/texture loading.

    I need it for my animations. When I change the animation of the soldier (for instance going from idle -> walk) in my game, sometimes the underlined texture isn't loaded and it would be great if I could find this out. Otherwise, for first couple of frames, the soldier is "teleported" to some location - because the texture isn't loaded yet. If I could then query the status of the texture, I could postpone the walk operation till the texture is fully loaded.

    Anyway, I think that handling the async resource management is a bit tricky. This is mainly because of inter-thread communication. There could still be point in the time when the system reports that all textures are loaded, but some may be added only recently and not noticed by the loading thread. Or could it?

    I think that some kind of determinism is needed there. For instance some hierarchical texture loading. For instance, make some root resource in the scene, and then parent all the other resources (textures, ...) to this root resource. And then wait for the root resources for complete, while querying the other resources status as was proposed by iarwain. I don't if it is possible to implements this.
  • edited February 2015
    iarwain wrote:
    One option would be to have a "start" texture load event, this way it'd be easy to know how many are pending without knowing how many textures are handled. I like this one, because it's an easy one. ;)

    Unfortunately the decompression is handled on a separate thread, via the task system, but there isn't any good query API yet, all that is available is orxThread_GetTaskCounter(), which won't filter out on task types. So I guess another option would be to add types to tasks and a way to filter them out on queries. I like it a bit less because it's more work for a rather independent problem, in the end. ;)

    When are you planning to send the "start" event? When you start accessing the disk, or decompressing the data? I think the former would solve the problem in combination with GetTotalPendingTaskCounter.

    I was also thinking about maybe doing this the other way round. Instead of counting unknown resource load events, we could also test our objects to see whether they've loaded all the resources they need. For instance, if we had a function like orxBOOL orxObject_AllResourcesReady(), we could recursively walk our object hierarchy (The real scene, or the preload dummy scene) and check if everything is in place. I think this would also be a more generic solution, enabling the loading of a level in phases. If we could disable the sounds on dummy preload objects without killing them, this solution would even extend to sound preloading. It would also be more "functional" since it only relies on the current state of the world, instead of watching events over a period of time. This is also similar to Trigve's suggestion if I'm not misunderstanding.
    PS: Thanks for the testbed, I'll use it to test whichever solution gets implemented.
    NP :) In any case, I needed to prepare something similar to it, to experiment with the loading screen.
  • edited February 2015
    Sausage: yes, the event is only sent after everything has been uploaded to the GPU, when you get it, it means that this texture is ready to be used, so in your case you should probably be good. :)

    Trigve: Sure, I can an orxTexture_IsReady() if that's what you meant. It'd rely on the underlying events to update its status. For the resource hierarchy, I'm not sure how to do that in a simple fashion, for both the engine and the end user.

    Enobayram: The "start" event would be sent upon as soon as the loading request is received, ie. even before starting the disk access task. The way I was seeing it was with a orxTexture_GetLoadingCounter() for example, that would reflect at any time how many textures are in the process of being loaded. When that number is 0, it means it's safe, as in no visual glitches will appear, to use any of the textures.
    The orxObject_AllResourcesReady() is also an option, but that would mean knowing exactly all the components and adding another redundancy for testing all different resources, which I'm not a huge fan but could live with, if need really be.
    You can disable the sound on dummies, either by pausing them upon creation or simply deactivating the owner object. I personally prefer the separate pre-load option (ie. not linked to the objects themselves but done in bulk at a given time) as this way I know two things:
    - no extra delay will be incurred when creating the object
    - no out-of-memory is likely to happen as all the resources that I'm going to use have already been loaded at the same time
    - I don't have to do any post-processing of my objects, I keep things data-driven by having the preload sections on one side, and the "live" ones on the other side, all I do is simply a one liner of creating an object hierarchy and having to inspect/modify it later on: the pre-load one deletes itself, the live one does what it's supposed to do

    But it's really a matter of personal preference, nothing more.
  • edited February 2015
    iarwain wrote:
    orxTexture_GetLoadingCounter() for example, that would reflect at any time how many textures are in the process of being loaded. When that number is 0, it means it's safe, as in no visual glitches will appear, to use any of the textures.
    The orxObject_AllResourcesReady() is also an option, but that would mean knowing exactly all the components and adding another redundancy for testing all different resources

    Actually, GetLoadingCounter() would solve my current loading problems. Except for sound, I know that sounds don't take long to load, but the human eye-ear coordination is precise enough to notice a millisecond delay in a pop sound, that was supposed to be synchronized to an object creation. So, if you're planning to "pop" objects right after the loading screen, you'd better be sure that the pop sound is already cached. I suggested orxObject_AllResourcesReady to solve a more general problem, where you might be separately interested in the statuses of subsets of your textures. Not that I need it now, nor that I have future plans that require it, just overengineering as a habit I'm trying to quit. I totally agree on the redundancy point though.
  • edited February 2015
    I do like the idea of having a centralized way to know if an object (or an object hierarchy) is ready to be used, it's just that, at the moment, some ground work needs to be done as async loading has been late to the party. :)

    First step would be to add the same notification pipeline for sounds (right now they're entirely loaded on a separate thread and no event is sent later on on the main thread). Then, when it's unified, we'd need to think how much control we want to give to the user and how much automatization we want to provide.

    In the simple case of using an object when everything's ready in it, that's not too bad, complexity comes in when people manually chunks resource and plug them on the fly in their animation sets, for example. ;)

    But for now, I'll try to homogenize the notification systems on textures and sounds. What do you think?
  • edited February 2015
    Hi,
    Your suggested orxTexture_IsReady() would be handy, but I would also need some functionality to get associated texture for the given animation. Some pseudo code:
    anim = orxAnim_CreateXXX(...);
    texture = orxAnim_GetTexture(anim);
    is_loaded = false;
    while((is_loaded = orxTexture_IsLoaded(texture) == false)
      yield;
    

    I like your last idea, to have some mechanism to know if the object is ready for the use. It was like the thing I was suggesting, maybe described badly in my post.

    How will it treat the hierarchies? Will the root object be ready to use only if all the children are ready to use?

    Another question is how would the complicated scene be loaded (similar to your example of "manually chunks resource and plug them on the fly" - I'm in that camp too) . I start the new scene. Show the loading screen, wait for the root object to be ready. But meantime, some other objects could be created by some already-ready objects and so waiting could be prolonged (or in theory, infinite if there are some cyclic dependencies:) ). Should I therefor after loading the root object pause it and wait till the object (and all the children automatically) would be in the ready state and only then unpause it and let it go?
    Now, in your example, when for instance the animation sets are created on the fly, the root object could be in the ready state in no time. But how would we know if all the "dynamic" stuff is in ready state? I do think that it is responsibility of the user to signal if the given object is in the ready state or not. But how would it be implemented? Maybe sending some ready event? Or some orxObject_SetIsReady() function?

    Thanks
  • edited February 2015
    iarwain wrote:
    In the simple case of using an object when everything's ready in it, that's not too bad, complexity comes in when people manually chunks resource and plug them on the fly in their animation sets, for example. ;)

    and

    Trigve wrote:
    But how would we know if all the "dynamic" stuff is in ready state? I do think that it is responsibility of the user to signal if the given object is in the ready state or not. But how would it be implemented? Maybe sending some ready event? Or some orxObject_SetIsReady() function?

    I think it would be reasonable to expect that if you're doing fancy stuff dynamically, you're responsible for making sure that everything is preloaded by the time you need them. If orxObject_IsReady (or something like that) takes care of what's visible in the config, one can easily preload dummy objects containing any extra resources. IMHO, that would be a nice compromise between automatic vs. manual. So maybe, if you have a simple scene, just create it during the load screen, but if you have more complicated stuff, load dummy objects in addition to your scene to take care of the fancy stuff.
    But for now, I'll try to homogenize the notification systems on textures and sounds. What do you think?

    I think that would be nice on its own, and it would certainly satisfy my current loading screen needs :)
  • edited February 2015
    enobayram wrote:
    I think it would be reasonable to expect that if you're doing fancy stuff dynamically, you're responsible for making sure that everything is preloaded by the time you need them. If orxObject_IsReady (or something like that) takes care of what's visible in the config, one can easily preload dummy objects containing any extra resources. IMHO, that would be a nice compromise between automatic vs. manual. So maybe, if you have a simple scene, just create it during the load screen, but if you have more complicated stuff, load dummy objects in addition to your scene to take care of the fancy stuff.

    I think it all depends on the implementation of the orxObject_IsReady(). I would welcome if the orxObject_IsReady() would scan the actual object (and also the children if some param is set to true) to find the all resources needed for the object and returning true if all of them are ready. Then all I need is this functionality and I take care of everything else myself. If the orxObject_IsReady() would be implemented in this fashion, I think no dummy objects may be needed.

    I'm not a fan of dummy objects :)

    Here is the workflow I would probable use:

    New scene loading - Load the actual scene from some file (or as part of old game load), create loading screen, create objects. Based on the object state (for instance soldier state - idle, walk, crouch, ...), change/add/delete stuff from the object (animation, effects, texture, ...). Now pause all objects so no state change could occurs. Wait till the root object's orxObject_IsReady() returns true (or if you have list of all your objects, you can iterater over it and call orxObject_IsReady() for each of them). Disable loading screen. Unpause root object.

    My 2 cents. I may be wrong, so feel free to point it out :)
  • edited February 2015
    maybe a bit out of topic:

    is there a reason why for preloading texture i can just do
    for(int i = 0; i < orxConfig_GetListCounter(szConfigPreloadTexturesList); i++)
    {
      orxTexture_CreateFromFile(orxConfig_GetListString(szConfigPreloadTexturesList, i));
    }
    

    but for sample i need to do
    for(int i = 0; i < orxConfig_GetListCounter(szConfigPreloadSoundsList); i++)
    {
      orxSOUND* pstSound = orxSound_CreateFromConfig(orxConfig_GetListString(szConfigPreloadSoundsList, i));
      orxSound_Delete(pstSound);
    }
    

    also, why is there a KeepInCache for Sound but not for Graphic (i know that for a Graphic that means to keep the whole Texture)
  • edited March 2015
    Mmh, sorry, I was sure I already answered that one. :/

    The reason is that there's an extra indirection with sounds.

    Textures map to the image files, whereas sounds map either to sample files or streams.

    You'll find the corresponding functions in the orxSoundSystem API (orxSoundSystem_CreateStreamFromFile & orxSoundSystem_LoadSample). However if you were to call them directly, the Sound module wouldn't know about them, so it wouldn't be of much help with respect to caching/pre-loading.
  • edited March 2015
    I just added orxTexture_GetLoadCounter() + Texture.GetLoadCounter command.
    Lemme know if there's any issue with that. I'll investigate the sound part soon.
  • edited March 2015
    Keen to get this into the current project.
  • edited March 2015
    iarwain wrote:
    I just added orxTexture_GetLoadCounter() + Texture.GetLoadCounter command.
    Lemme know if there's any issue with that. I'll investigate the sound part soon.
    Nice it saves me from handling the counts in client code, will try it out this weekend B)
  • edited March 2015
    I'll be adding a similar path for the sound during the week, but it requires a few more changes as the PLAY events were not entirely accurate (they were sent when the order was transmitted, not when the sound was actually starting to play, so I need to change that first).
  • edited July 2015
    Hi Guys,

    Just revisiting this problem now that the orxTexture_GetLoadCounter has been introduced. I managed to greatly improve my texture loader bar routine.

    However the intermittent race condition during texture loads for Android still occurs.

    In short, the texture loading process for desktop platforms is fine. But in 50% of cases, an Android application will seize. I know the application has not fully frozen or crashed, as the music can still be heard in the background until the watchdog on the android device finally resets it.

    I simplified my Texture Handler to help diagnose the problem. I removed unnecessary code, so that it just outputs the event type and the texture count remaining:
    orxSTATUS orxFASTCALL RasterBlaster::TextureLoadingEventHandler(const orxEVENT *_pstEvent) {
        
        orxLOG("TextureLoadingEventHandler START");
        
        orxU32 texturesRemainingCount = orxTexture_GetLoadCounter();
        orxLOG("texturesRemainingCount in TextureLoadingEventHandler(): %d", texturesRemainingCount);
        
        if (_pstEvent->eType == orxEVENT_TYPE_TEXTURE){
            
            if (_pstEvent->eID == orxTEXTURE_EVENT_CREATE){
                orxLOG("orxTEXTURE_EVENT_CREATE");
            }
            
            if (_pstEvent->eID == orxTEXTURE_EVENT_DELETE){
                orxLOG("orxTEXTURE_EVENT_DELETE");
            }
            
            if (_pstEvent->eID == orxTEXTURE_EVENT_NUMBER){
                orxLOG("orxTEXTURE_EVENT_NUMBER");
            }    
            
            if (_pstEvent->eID == orxTEXTURE_EVENT_NONE){
                orxLOG("orxTEXTURE_EVENT_NONE");
            }    
            
            if (_pstEvent->eID == orxTEXTURE_EVENT_LOAD){
                
                orxTEXTURE *pstSenderObject;
                pstSenderObject = orxTEXTURE(_pstEvent->hSender);
                
                const orxSTRING name = orxTexture_GetName(pstSenderObject);
                orxLOG("orxTEXTURE_EVENT_LOAD %s loaded.", name);
                
            }
        }
        
        orxLOG("TextureLoadingEventHandler END");
    }
    


    Using this code I managed to produce the log from the Android device. See attached. Notice that on Init(), there are already 7 textures to load. This rises up to 38 Create Events, and then this decreases as the Loading Events fire.

    Finally we get to 8 textures remaining, where the something goes a little haywire.

    Again, this is only a problem on Android. Perhaps this is mostly a post for lydesik, but interested on any general thoughts. https://forum.orx-project.org/uploads/legacy/fbfiles/files/texture1.txt
  • edited July 2015
    A slight log improvement would be to add the name of the texture upon creation as well. Something like (untested):
    orxLOG("orxTEXTURE_EVENT_CREATE %s created", orxTexture_GetName(orxTEXTURE(_pstEvent->hSender)));
    
  • edited July 2015
    I'm curious to know why the load counter starts that high instead of starting at 0.
    Also, what is the log result on desktop, to compare?
  • edited July 2015
    Also I noticed that the workflow might be a bit broken in synchronous mode and when texture loadings fail. I'll check all that tonight. :)
  • edited July 2015
    iarwain wrote:
    A slight log improvement would be to add the name of the texture upon creation as well. Something like (untested):
    orxLOG("orxTEXTURE_EVENT_CREATE %s created", orxTexture_GetName(orxTEXTURE(_pstEvent->hSender)));
    

    Cool, will upload a version with creation names as well.
  • edited July 2015
    iarwain wrote:
    I'm curious to know why the load counter starts that high instead of starting at 0.
    Also, what is the log result on desktop, to compare?

    I did notice that. Desktop logs always start at 0. I theorised that perhaps Android was slower to initialise and that textures had already queued.

    In the case of this log where the texture count start at 7, perhaps it misses out on some CREATE events, throwing some kind of count out. Just a thought.

    I'll get a desktop version of the log.
  • edited July 2015
    Attached is a desktop version + create names.

    Won't have access to an android build until this evening to put creation names in, but this should help compare. https://forum.orx-project.org/uploads/legacy/fbfiles/files/texture_desktop.txt
  • edited July 2015
    On my side, I checked the workflow in synchronous mode, but it was actually fine, I misread it this morning.
    I did fix the workflow when a texture decompression fails though, as before the load counter wouldn't be updated.
    Now the counter gets updated but no load event will be sent, an empty texture will be created and used in place of the faulty one, with a log explaining what happened. That was just as a FYI as I doubt it was your case anyway.

    One other thing to do on Android would be to add logs inside orxTexture.c everytime the load counter gets increased or decreased, as well as the texture name associated with the operation. That should give us all the visibility we need to understand what's going on.
  • edited July 2015
    iarwain wrote:
    add logs inside orxTexture.c everytime the load counter gets increased or decreased, as well as the texture name associated with the operation. That should give us all the visibility we need to understand what's going on.

    Yep, all done for desktop. See attached. https://forum.orx-project.org/uploads/legacy/fbfiles/files/desktop_textures_full_logging.txt
  • edited July 2015
    And here's the one for Android. I included lots of logging lines before and after, in case it helps. In this example, the count got down to 3 before seizing: https://forum.orx-project.org/uploads/legacy/fbfiles/files/android_textures_full_logging.txt
  • edited July 2015
    Thanks for the logs, Sausage!

    We're getting closer but I think we'll need logs inside the Android display plugin now. Mostly in the Decompress and DecompressCallback to see where things get stuck.
    Also could you try the latest version of orx, I made a couple of changes that could potentially help with any loading issue?
  • edited July 2015
    Hi sausage,

    So I didn't test your issue, but I never had this before...
    I've googled for the "GetBufferLock timed out" error and here is what I found.

    All the post about this error were reported on Tegra2 GPU (same as your), and they are all related to graphics stuffs (textures etc...)

    There may be different reasons for this error, but most probably a poorly designed locking mechanism for GPU memory allocation. Maybe GPU runs out of memory, and fails to unlock something, really hard to tell.

    My conclusions:
    Your device sucks (sorry. I know because I owned an Asus Transfromer with the same GPU. still works great as a doorstop).
    Issue is really low level and Orx probably wont be able to recover from this. ever.
  • edited July 2015
    iarwain wrote:
    Thanks for the logs, Sausage!

    We're getting closer but I think we'll need logs inside the Android display plugin now. Mostly in the Decompress and DecompressCallback to see where things get stuck.
    Also could you try the latest version of orx, I made a couple of changes that could potentially help with any loading issue?

    Yes will do. Starting shortly. I saw the commits from Lydesik and yourself today so I've been keen to try again.
  • edited July 2015
    lydesik wrote:

    My conclusions:
    Your device sucks (sorry. I know because I owned an Asus Transfromer with the same GPU. still works great as a doorstop).
    Issue is really low level and Orx probably wont be able to recover from this. ever.

    In a strange sort of way, this gives me some comfort. I just didn't like the idea that all these android devices would try my game and seize up half the time. But if it's down to just one GPU, I guess I can live with it and move on.

    Thing is... it doesn't have to be asynchronous loading. I'm happy with synchronous loading of textures, if it were possible.

    Anyway, I'll go through the motions with some new logs for the sake of completeness.
  • edited July 2015
    well, you can disable asynchronous texture loading with orxDisplay_SetTempTexture(orxNULL);

    but, my bet is it won't change a thing.
  • edited July 2015
    Guess I'll just have to take that on advice then. No point letting this issue hold up the title release.

    Tried adding logging to the plugin file but nothing logged. Too tired to see why tonight.
Sign In or Register to comment.