Hi,
I'm working on a project that uses @napi-rs/canvas (which wraps Skia) for running canvas-based games on low-RAM embedded devices. I've tracked down a performance issue where drawing one raster surface onto another is about 8x slower than drawing an SkImage.
I traced it to SkSurface_Raster::onDraw in src/image/SkSurface_Raster.cpp:
void SkSurface_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
const SkSamplingOptions& sampling, const SkPaint* paint) {
canvas->drawImage(fBitmap.asImage().get(), x, y, sampling, paint);
}
As I understand it, fBitmap.asImage() ends up in SkImage_Raster::MakeFromBitmap with SkCopyPixelsMode::kIfMutable. Since the surface's backing bitmap is mutable, this triggers a full pixel copy via RasterFromPixmapCopy() on every draw call.
I noticed there's a makeTemporaryImage() API that avoids the copy. Would it make sense for SkSurface_Raster::onDraw to use that instead? Or is there a reason it needs to go through asImage()?
I'm not strong in C++ so apologies if I'm misreading something. Happy to provide more context or test anything.
I would have filed this on the issue tracker directly, but I haven't been able to get access - I did sign the CLA though!
Related discussion:
https://github.com/Brooooooklyn/canvas/issues/972Thanks!
Luis Montes