图片资源到纹理资源再到GPU纹理,从spriteFrame说起
加载一个spriteFrame资源,它依赖Texture2D对象,Texture2D对象依赖ImageAsset对象,imageAsset对象依赖真正的native的图片资源。
从加载开始:
1. GPU纹理对象的创建
1.1在Texture2d对象被加载之后,会走一次ImageAsset的onLoaded方法

最终会走到ImageAsset的extractMipmaps方法,生成对应的mipmap对象:



生成的mipmap对象底层用的是同一份底层的数据,数据来源于加载后解析imageAsset对象时生产的数据。
1.2 根据生成的mipmap重置数据-》reset的流程

设置texture2d的纹理基础数据

通过device,适配不同的渲染适配类,比如webgl,webGPU等不同渲染平台的渲染类来处理

此时,已经调用对应的渲染适配的类,然后这个类去调用对应的渲染创建一个GPU纹理对象,此时还没有上传任何像素数据
1.3 reset之后的 assignImage流程
这里是真正上传像素数据到GPU上的流程

同样的最终会调用到适配不同渲染底层类的方法,去copyBufferToTexture方法。


一种是从source的数据缓存中的数据直接拷贝到GPU中
一种是将原始图像的数据拷贝到GPU中
2.以webGL为例看一下具体的创建纹理,与上传像素数据的流程
2.1 创建纹理

webgl中适配层创建纹理对象:

创建_gpuTexture对象,然后由传入的TextureInfo填充,另一部分由GL命令填充(这里还会计算一个显存大小)

WebGLCmdFuncCreateTexture会根据具体传入的纹理类型做不同的处理,并且调用真正的gl命令与GPU真正进行渲染命令的调用

涉及到的GL命令说明:
createRenderbuffer:创建一个渲染缓冲对象(Renderbuffer)的句柄,用于离屏的深度/模板缓冲(仅在不支持深度纹理且格式含深度时走这条分支)
gl.bindRenderbuffer:将指定的渲染缓冲绑定到 Renderbuffer 目标,使其成为后续渲染缓冲操作的作用对象。
gl.renderbufferStorage:为当前绑定的渲染缓冲分配指定内部格式和尺寸的存储(如深度缓冲),是渲染缓冲版的"分配显存"
gl.createTexture():创建一个纹理对象(GPU 显存中的纹理句柄),作为普通 2D / Cube 纹理的载体
gl.bindTexture:将纹理对象绑定到活动纹理单元上的目标(TEXTURE_2D 或 TEXTURE_CUBE_MAP),使其成为后续纹理操作的作用对象
gl.compressedTexImage2D:为压缩格式 纹理分配指定 mipmap 层级(level)的存储并上传数据(data 这里传的是大小为该层级尺寸的空 Uint8Array)
gl.texImage2D:为非压缩格式 纹理分配指定 mipmap 层级的存储并上传像素数据(data 传 null,即只分配显存不填数据)。注意creator这里上传的为null
gl.texParameteri:设置纹理采样参数,被调用 4 次,分别设置
-
TEXTURE_WRAP_S:S 方向(横向)环绕方式。若是 2 的幂(isPowerOf2)则为REPEAT,否则为CLAMP_TO_EDGE(非 2 的幂纹理必须钳制边缘,否则 WebGL1 报错)。 -
TEXTURE_WRAP_T:T 方向(纵向)环绕方式,规则同上。 -
TEXTURE_MIN_FILTER:缩小过滤器,固定为LINEAR。 -
TEXTURE_MAG_FILTER:放大过滤器,固定为LINEAR。
2.2 上传纹理像素数据



- 绑定纹理对象bindTexture,会利用缓存减少这个gl命令的调用
- 准备与格式相关的元数据
- 计算上传需要用到的数据:偏移、宽高、以及对应的像素数据(这里有一些特殊处理)
最终进行像素上传gl命令调用

至此,整个像素已经从CPU端传到GPU端
3.以流程图的方式回顾一下整个流程

