我目前正在尝试使用 FPDF_RenderPageSkia 直接渲染 PDF 页面到 GPU 加速的 SkCanvas 上。以下是我最初尝试的代码:
std::unique_ptr<SkPictureRecorder> recorder = std::make_unique<SkPictureRecorder>();
recorder->beginRecording(width, height);
SkCanvas* canvas = recorder->getRecordingCanvas();
// 将 PDF 页面渲染到记录的 canvas 上
FPDF_RenderPageSkia(reinterpret_cast<FPDF_SKIA_CANVAS>(canvas), page, width, height);
sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture();
// 创建 GPU surface 并将 SkPicture 绘制到上面
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(grContext.get(), (skgpu::Budgeted)0, info);
surface->getCanvas()->clear(SK_ColorWHITE);
surface->getCanvas()->drawPicture(picture);
这段代码可以正常渲染并调用到 GPU,但 FPDF_RenderPageSkia() 实际上是在 CPU 上执行的。也就是说,它只是录制成了 SkPicture,之后再绘制到 GPU surface 上,这并不是我想要的效果。
于是我修改了代码,尝试直接渲染到 GPU 加速的 canvas:
SkImageInfo info = SkImageInfo::Make(width, height, kUnknown_SkColorType, kPremul_SkAlphaType);
sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(grContext.get(), skgpu::Budgeted::kNo, info);
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorWHITE);
FPDF_RenderPageSkia(reinterpret_cast<FPDF_SKIA_CANVAS>(canvas), page, width, height);
但这样的话 SkSurfaces::RenderTarget() 会返回 nullptr,因此我无法获得一个有效的 SkCanvas。
我的问题是:
如何才能创建一个适用于 FPDF_RenderPageSkia 并真正支持 GPU 加速的 SkSurface 和 SkCanvas,从而使 PDF 渲染真正发生在 GPU 上,而不是通过 CPU 先生成 SkPicture 再绘制?
如果您能提供关于 SkImageInfo 正确配置的方法,或者确认 FPDF_RenderPageSkia 是否支持直接 GPU 渲染,将非常感谢!