agamemnus

Pixi.js caching

Recommended Posts

HI,

 

well textureCache is created every time you call new PIXI.Texture.fromImage and it checks if it (or baseTexture) is already saved in the cache in order to prevent downloading the texture again and again.... from your server if it is already loaded. Imagine creating a rain effect and preparing the raindrops in a for loop with i <= 200;

 

Without texture cache this would mean that you would have to call your server 200 times.

 

texture cache is created from two elements. 

 

The textureCache and the baseTexture. (Every texture cached has a base texture under it)

 

If you'll remove the textureCache by calling .destroy() this will remove the texture but leave the base texture still in your memory. Practically this means that if you have a sprite on a stage and you call destroy() on the texture. The sprite uploaded to the stage will still be renderable. But after doing this if you would call the same (previously deleted texture) it would reupload it from server.

 

Using the destroy(true) method on a texture removes the textureCache and the baseTexture. Practically if you would use this method with true argument on a texture used by a sprite that is on your stage the sprite would become black. 

 

baseTextures are heavily used in WebGl context to speed up calculations with the use of gl methods.

 

as for turning this off...... no i don't thinks so. Why would you like to do something like that?

 

http://www.sevenative.com

Share this post


Link to post
Share on other sites

Back to this. Where is the cached texture stored? What if I want to modify the cached texture (and it is a 2d texture), by, for example, drawing a line stroke on it? How can I do this?

 

I tried changing the texture's ".baseTexture.source", but after the first time, no changes are made to it. The renderer is webgl, and the baseTexture.source is forced as 2d.

Share this post


Link to post
Share on other sites

Back to this. Where is the cached texture stored? What if I want to modify the cached texture (and it is a 2d texture), by, for example, drawing a line stroke on it? How can I do this?

 

I tried changing the texture's ".baseTexture.source", but after the first time, no changes are made to it. The renderer is webgl, and the baseTexture.source is forced as 2d.

 

https://github.com/GoodBoyDigital/pixi.js/issues/949#issuecomment-54502749

Share this post


Link to post
Share on other sites

Wait, hold on a second.... so the texture created using fromCanvas is forced as 2d, it isn't webGL... so why do I need to update the webGL textures? Maybe I am not understanding something.

 

For example:

 

canvas.texture = new PIXI.Texture.fromCanvas (canvas)

 

When I do this, "canvas.texture.baseTexture.source" is the same as "canvas".

Share this post


Link to post
Share on other sites

But it is 2d... the texture.baseTexture.source is 2d. If it is 2d, isn't it in the cpu? Or what. Maybe a diagram would help...

 

That doesn't make any sense, WebGL is a 2D api. You draw "3D" stuff by projecting to 2D points and rendering those (rasterizing). When you are using the WebGL renderer and you use a canvas as a texture, that texture is uploaded to the GPU for rendering. The source being 2D doesn't change that you are using the WebGL renderer.

Share this post


Link to post
Share on other sites

When I say 2d I mean "2d" context.

 

(just as a reminder, renderer is in webgl mode in all the below examples...)

 

Ok, so it's always uploaded to a texture, regardless of what texture.baseTexture.source is? I am still extremely confused. :|

 

 

This creates a 2d baseTexture.source:

canvas.texture = new PIXI.Texture.fromCanvas (canvas)

 

This creates a webgl baseTexture.source:

somethingelse.texture = new PIXI.Texture.fromCanvas (canvas)

 

So a few more questions please:

* What is baseTexture.source used for?

* Why is it that I can modify the 2d canvas (baseTexture.source) ONCE via a canvas 2d drawing operation, and then can't modify it again?

* Where is the texture actually stored? Can I get to it from JS?

* In webgl mode, is *everything* somehow uploaded to a webgl context (or texture set, I guess??)?

Share this post


Link to post
Share on other sites

There isn't a "2d baseTexture.source" and "webgl baseTexture.source". There is just a canvas, or image, or video, etc. The context of drawing to the canvas has nothing to do with the actual canvas. WebGL has support for binding a canvas as a texture, just like canvas has drawImage(canvas) support. The context you create means nothing to how we use the canvas after you draw to it.

 

- baseTexture.source is the source of the texture, it is what is used to draw that texture. For WebGL this is what is bound to a TEXTURE_2D and sent to the GPU, for canvas it is passed into the "drawImage" call.

- You can modify it as much as you want, you just have to update the gl texture so the GPU knows to draw something else. We need to know to rebind the texture.

- "the texture actually stored" is ambiguous, there is the pixi texture object, the texture's source (your canvas), and the gl texture (webgl object). You can access all those things via js, that is how you update in the code snippet I posted.

- Yes, otherwise it can't be drawn. There is only one canvas, and you can only have one drawing context into it (that is '2d' or 'webgl' but never both). TO draw with WebGL you need to bind the texture to GPU memory and draw it.

 

Basically you need to call "PIXI.updateWebGLTexture" so that we can rebind the texture to the GPU. You can see what is does here:

 

https://github.com/GoodBoyDigital/pixi.js/blob/master/src/pixi/renderers/webgl/WebGLRenderer.js#L457

 

Note that this method changes a little in the next version of PIXI:

 

https://github.com/GoodBoyDigital/pixi.js/blob/dev/src/pixi/renderers/webgl/WebGLRenderer.js#L393

 

 

Basically:

 

A source is a raw, drawable, item (like a canvas, image, video, etc).

A BaseTexture is a wrapper object for a source, that holds some meta data.

A Texture is an application of a view into a BaseTexture based on a frame.

A Sprite is a renderable object that is visually represented by a Texture.

Share this post


Link to post
Share on other sites

All right....... ooooooooone more question.

 

If a "BaseTexture.source" is uploaded to the gpu via the binding, is it theoretically safe to clear it after it is uploaded to save RAM? ... sorry if that is an infuriating question. :-|

Share this post


Link to post
Share on other sites

You wouldn't have that element garbage collected, because we are using the object in PIXI (and therefore have internal references). Not until you remove it from pixi do we remove all our references (and therefore from being rendered) will it actually give you any memory back. At which point you can render it anymore so it is moot.

Share this post


Link to post
Share on other sites

So are you saying that I have to have the texture both in the CPU and the GPU? Or are you saying that the "upload to the GPU" transfers the texture to the GPU, and:

* If it's a 2d context, makes a copy.

* If it's a webgl context, creates a pointer to the context.

 

:-( ?

Share this post


Link to post
Share on other sites

It is never copied (in system memory), there are times where the texture will live in GPU memory and system memory but that is normal and totally fine. Basically you create a gl texture, bind the source to is (think of a glTexture like PIXI's baseTexture), then it gets sent to the GPU when drawing.

 

We keep a reference to the texture (which has a reference to the source):

 

https://github.com/GoodBoyDigital/pixi.js/blob/b29acff1455117567440acdb9fc16f9d1d5670db/src/pixi/renderers/webgl/WebGLRenderer.js#L413

 

Even if you remove all your references to the canvas, the glTexture still has a reference to it so it doesn't get cleaned up (because GPU memory may need to have texture swapping based on memory size, applications, etc). The only "copy" is the pixel array sent to the GPU. But that is just how that works, regardless of the type of context.

 

If you are drawing something, you shouldn't be deleting it out of memory. You can't, and will likely just break things if you somehow got that to happen. When you are done drawing it, you can call .destroy(true) on the PIXI.Texture and it will remove all related memory for you. Then just lose your own references and let the GC do it's job.

Share this post


Link to post
Share on other sites

If you are using the CanvasRenderer you don't need todo anything, as you draw to the texture source it just works. If you are using the WebGLRenderer you need to call the methods I linked to update the texture we have on the GPU whenever you update the texture source.

 

What your drawing context is to the source of your texture does not matter.

Share this post


Link to post
Share on other sites

PIXI.updateWebGLTexture (or the dev version) just does not work.

 

updateWebGLTexture = function(texture, gl)

 

Notice it is asking for a webgl context. I only have a 2d context.

 

I don't think you read the original post I sent you. You don't pass the context of the texture's source, you are passing the gl context that the *renderer* is using, most commonly:

PIXI.updateWebGLTexture(myTexture.baseTexture, myRenderer.gl);
To be more clear about that is why the fn is changing in the next version

Share this post


Link to post
Share on other sites

Thanks, got it!

 

The .baseTexture part is a bit of a gotcha.. would have just expected .texture.

Which is why the next version is "renderer.updateTexture(texture)" to clear-up confusion. Originally this function was only used internally, which is why it looks weird.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.