SkImage_Raster用来处理存在堆上是 RAW数据的图像,即光栅类型的图像。
SkImage_Raster对象关联有一个SkBimap对象,SkBimap对象关联一个SkPixelRef对象。SkPixelRef对象保存着图像数据。
skia绘制SkImage_Raster时,会先创建一个GrTexture实例(GrTexture是对GPU纹理单元的抽象,一个GrTexture实例,表示一个纹理单元),然后把SkImage_Raster的图像数据上传到GrTexture实例所表示的纹理单元,最后进行渲染。
如果多次绘制同一个SkImage_Raster实例,skia并不会重复创建GrTexture实例上传纹理数据。
SkImage_Raster.fBitmap.fPixelRef有个成员变量fUniqueID,GrTexture有个成员变量fUniqueKey。首次绘制SkImage,创建GrTexture实例时,会根据fUniqueID来设置GrTexture的成员变量fUniqueKey,相当于建立了SkImage和GrTexture对应关系。另外,skia的内存管理模块会把创建GrTexture实例缓存起来。后续绘制同一个SkImage时,会根据fUniqueID去缓存查找GrTexture实例,没有查找到才会创建GrTexture实例。如果查找到了,就会复用。
整个流程如下:
通过上面的分析,知道了SkImage_Raster缓存和SkImage_Raster.fBitmap.fPixelRef.fUniqueID进行映射关联的。缓存能否命中关键看SkImage_Raster.fBitmap.fPixelRef.fUniqueID。
SkImage_Raster.fBitmap.fPixelRef.fUniqueID的值是怎么设置的呢?
如果这个SkImage_Raster实例是由Bitmap创建的,则SkImage_Raster的fBitmap.fPixelRef指向的是创建SkImage_Raster的Bitmap,SkImage_Raster.fBitmap.fPixelRef.fUniqueID的值就是Bitmap的fUniqueID的值。Bitmap的fUniqueID的值是在Bitmap创建的时候设置的。流程如下:
UML图更能清楚的展示了这一关系:
这里需要注意的是,Bitmap的fUniqueID的值不是固定不变的。如果触发了Bitmap::reconfigure的执行,Bitmap会更新fUniqueID的值。这样就会导致缓存失效,下次再绘制这个Bitmap时,就会出现GrTexture重新创建和纹理上传。
另外,除了触发Bitmap::reconfigure的执行会导致缓存失效外,trimMemory操作也会导致缓存失效。trimMemory操作触发skia缓存回收操作,从而导致缓存失效。