Android为什么要使用pinImages将可变位图的纹理上传到GPU?

问题描述

当我阅读Android源代码SkiaRecordingCanvas时,发现如果将位图标记为可变的,即!isImmutable() == true,则该位图将通过函数SkiaPipeline::pinImages缓存在GPU中,该函数调用Skia界面SKImage_pinAsTexture。但是,当我在pinImages中注释了这些行并重新编译并推送到电话后,我发现gif显示正常。唯一的区别是纹理上传prepareTree延迟到renderFrameImpl。那么,为什么Android使用这种方法来缓存可变位图的纹理?

bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
    // for (SkImage* image : mutableImages) {
    //     if (SkImage_pinAsTexture(image,mRenderThread.getGrContext())) {
    //         mPinnedImages.emplace_back(sk_ref_sp(image));
    //     } else {
    //         return false;
    //     }
    // }
    return true;
}

解决方法

即使基础位图发生更改,固定和取消固定也可以正常工作。

固定它会导致图像急切地上传到GPU。取消固定它可以释放与GPU相关的内存。请参阅https://github.com/google/skia/blob/dc3332a07906872f37ec3a592db7831178886527/src/core/SkImagePriv.h#L62-L86

上的文档

通过注释掉这段代码,您正在做它,以便直到(接近绘制时)图像才(或至少不会)上传到GPU,这可能导致更多的工作要做在不幸的时候,尤其是在低端设备上。我还不清楚在没有匹配的unpin的情况下调用pin有什么后果。