_dispose(force = false) {
        if(this.sourceType === "video" || this.sourceType === "image" && !this.renderer.state.isActive) {
            // remove event listeners
            if(this._loader) {
                this._loader._removeSource(this);
            }

            // clear source
            this.source = null;
        }
        else if(this.sourceType === "canvas") {
            // clear all canvas states
            this.source.width = this.source.width;

            // clear source
            this.source = null;
        }

        // remove its parent
        this._parent = null;

        // do not delete original texture if this texture is a copy, or image texture if we're not destroying the context
        const shouldDelete = this.gl && !this._copiedFrom && (force || this.sourceType !== "image" || !this.renderer.state.isActive);

        if(shouldDelete) {
            this._canDraw = false;

            // if the texture is in our textures cache array, remove it
            this.renderer.cache.removeTexture(this);

            this.gl.activeTexture(this.gl.TEXTURE0 + this.index);
            this.gl.bindTexture(this.gl.TEXTURE_2D, null);
            this.gl.deleteTexture(this._sampler.texture);
        }
    }
This is used to destroy a texture and free the memory space
     Usually used on a plane/shader pass/render target removal

     params:
     @force (bool, optional): force the texture to be deleted even if cached
*