Author Topic: Rapid Texture loading/unloading  (Read 2034 times)

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Rapid Texture loading/unloading
« on: February 10, 2014, 12:14:51 pm »
So, I have a problem when rapidly loading and unloading textures in a multithreaded environment with several viewports, worlds, etc

In particular the problem occurs when unloading a texture, then immediately loading it again (same image and name) and creating an object that uses the texture (all without redraw). The texture then appears without the texture and is colored in the setAdditionalColor(...) color. I suspect that the texture doesn't get unloaded from the FrameBuffer. However when I add another object with the same texture "a little bit later" (after redraw), it is textured fine.

I tried to create a simple test case, but no luck. The workaround I have now is that I use

Code: [Select]
        if (textureManager.containsTexture(name)) {
            textureManager.replaceTexture(name, texture);
        } else {
            textureManager.addTexture(name, texture);
            textureManager.replaceTexture(name, texture);
        }

Will this cause a lot of extra load? How bad practice is this?

Thank you!

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #1 on: February 10, 2014, 12:21:59 pm »
jPCT isn't thread safe. Fiddling around with textures from outside the rendering thread can lead to all kinds of funny race conditions. While your solution might improve this, i doubt that it will work in all cases. I would rather put that code into the rendering thread or synchronize both operations (i.e. rendering and texture updates).

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #2 on: February 10, 2014, 12:45:48 pm »
They are already synchronized. Also the behavior is very consistent and my approach always stops the problem from occurring (in my tests anyway).

The only thing that was multithreaded w.r.t. rendering, world or texture modification is JPCT itself. I just disabled that and the problem still occurs. Will try to get you that test case... (or maybe find my own stupidity while doing so =)
« Last Edit: February 10, 2014, 12:49:32 pm by aZen »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #3 on: February 10, 2014, 01:09:34 pm »
They are already synchronized.
...synchronized on what?

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #4 on: February 10, 2014, 09:05:59 pm »
God... I was finally able to create a test case that reproduces the bug. Cleaning it up now, but will post soon!

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #5 on: February 10, 2014, 09:41:57 pm »
Here you go.

http://blackflux.com/software/vs/download/?file=BugTestCase.zip

I wanted to simplify it more, but it behalves.. very strange. So I decided to leave it as it is. The non-java files are the textures that are loaded (png images).


Screenshot of the bug: Texture is available but not displayed.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #6 on: February 10, 2014, 09:48:47 pm »
That test case is confusing...what does it do?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #7 on: February 10, 2014, 10:06:48 pm »
...i think that this test case either doesn't reproduce your actual problem or it's not a bug. If you comment out these two lines:

Code: [Select]
//removeTexture("f0e482dac89c9456011090337316d7c1");
        removeObjectById(15);
        obj.build();
        world.addObject(obj);
        trackObjectId(obj, 26);
        obj = new Object3D(2);
//loadTexture("f0e482dac89c9456011090337316d7c1");

it works fine. And that's to be expected, because, like the docs for removeTexture say:

Quote
Please note that you can't expect an object that uses this texture to get a new texture that you might add with the same name after removing this one. If you want to replace textures on objects, use replaceTexture() instead.


Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #8 on: February 10, 2014, 10:17:59 pm »
No, that is exactly the problem that I found. I read the doc, but thought that it doesn't apply. Let me explain:

So basically what happens is

addTexture("a", img1);
addObjectWithTexture(obj1, "a");
removeObject(obj1);
removeTexture("a");
addTexture("a", img1);
addObjectWithTexture(obj2, "a");

Note that the texture (when it exists) always contains the same image.

I'm not expecting an object to update, just expecting that it shows any texture (old or new version doesn't matter, they're the same anyway) when I create it and the texture exists in the TextureManager. Instead the object doesn't show a texture.

If you say it's expected I'm happy to add an replaceTexture after the addTexture (as described in the first post) and forget about it.
« Last Edit: February 10, 2014, 10:33:47 pm by aZen »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #9 on: February 10, 2014, 11:08:27 pm »
I see...no that's not to be expected. This version should fix it: http://jpct.de/download/beta/jpct.jar

However, due to the internal structure of the TextureManager, it's always better to replace a texture with the same name instead of doing a remove/add combination regardless of the texture being used by some object or not.

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #10 on: February 10, 2014, 11:16:45 pm »
Great, thank you. That fixes it!

Yes, that was what I figured. Unfortunately because of how I have organized things it's very tricky to do that in the particular case.

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #11 on: February 10, 2014, 11:31:07 pm »
After spending so much time tracking this down I have to ask: What was causing it?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Re: Rapid Texture loading/unloading
« Reply #12 on: February 10, 2014, 11:49:18 pm »
A simple cache that should have been cleared when you remove a texture but wasn't.

Offline aZen

  • int
  • **
  • Posts: 94
    • View Profile
Re: Rapid Texture loading/unloading
« Reply #13 on: February 11, 2014, 12:46:11 am »
Hehe, always the simple things causing the biggest issues.

Thank you for fixing this so fast!