samizdatco / skia-canvas

A GPU-accelerated 2D graphics environment for Node.js
MIT License
1.67k stars 63 forks source link

Error: Could not allocate new bitmap #111

Open mikhailsdv opened 2 years ago

mikhailsdv commented 2 years ago

Version 1.0.0 throws Error: Could not allocate new 100x100 bitmap error when trying to save/buffer result image.

const canvas = new Canvas(100, 100)
const ctx = canvas .getContext("2d")
await canvas.toBuffer("jpg") //error

Downgrade to 0.9.30 fixes the issue.

samizdatco commented 2 years ago

Thanks for the bug report.

A few questions:

  1. What OS are you running this on?
  2. Is canvas.gpu reporting true or false
  3. If it's true, does setting it to false before saving work?
mikhailsdv commented 2 years ago
  1. Windows 11 Pro (Build 22000.795)
  2. canvas.gpu returns true
  3. I've set it to false and it fixed the issue.
samizdatco commented 2 years ago

Interesting. So that means it's passing the test where it tries to create a Vulkan context (which is currently how it decides whether to enable GPU rendering), but failing when it attempts to create a surface with it.

Do you happen to know what video card/driver versions you're using (and whether they include Vulkan support)?

samizdatco commented 2 years ago

I've updated the code that checks for Vulkan support to try allocating a surface before enabling GPU support. Could you try installing the current release candidate and let me know if canvas.gpu is now disabled by default?

You can install the new version (1.0.1-rc1) with:

npm install https://github.com/samizdatco/skia-canvas
mikhailsdv commented 2 years ago

I've reinstalled skia-canvas as you described. Now when i run console.log(canvas.gpu) it returns false. My laptop uses Intel UHD Graphics 620 video card, but as i know it supports Vulkan.

image

TaufiqSyed commented 2 years ago

^^ Having the same issue. I've verified Vulkan is working on my system though, so I'm not sure what's the reason for the problem.

samizdatco commented 2 years ago

^^ Having the same issue. I've verified Vulkan is working on my system though, so I'm not sure what's the reason for the problem.

Are you also running on Windows with an Intel video card?

samizdatco commented 2 years ago

One other thing I'm curious about for those of you seeing this bug: does new Window() generate any interesting error messages? It uses a slightly different method of attempting to initialize Vulkan...

mikhailsdv commented 2 years ago

Version 1.0.1-rc1 👇

image    

Version 1.0.0 👇

image

TaufiqSyed commented 2 years ago

Are you also running on Windows with an Intel video card?

I'm running on Fedora Linux with an NVIDIA GeForce MX250 video card. Also having the same results as Mikhail in regards to the using new Window().

samizdatco commented 2 years ago

That's a good sign that it's able to render to a window at least (though I'm still struggling to identify what the key difference is that makes one work and one fail). I've made a small tweak to surface creation in rc2:

npm install https://github.com/samizdatco/skia-canvas

Let me know if it improves the non-window behavior (both in terms of reporting canvas.gpu to be true and then being able to save or create a buffer from it).

TaufiqSyed commented 2 years ago

It's behaving the same as the previous release candidate where canvas.gpu defaults to false. It might be an issue on my end, however I'm not sure what I'm doing wrong. Is there any foolproof way to check Vulkan is working properly?

samizdatco commented 2 years ago

Is there any foolproof way to check Vulkan is working properly?

Just to clarify: can you successfully open a window with new Window() and draw to its canvas?

mikhailsdv commented 2 years ago

Tested both with rc2:

const {Canvas, Window} = require("skia-canvas")

;(async () => {
    const canvas = new Canvas(100, 100)
    console.log(canvas.gpu) // false
    canvas.gpu = true
    console.log(canvas.gpu) // still false
    const ctx = canvas.getContext("2d")
    await canvas.toBuffer("jpg") //works fine
})()

;(async () => {
    const win = new Window(300, 300) // successfuly opens a window
    console.log(win.canvas.gpu) // false
    win.canvas.gpu = true
    console.log(win.canvas.gpu) // also false
    win.ctx.fillStyle = "red"
    win.ctx.fillRect(100, 100, 100, 100) // works fine
})()
samizdatco commented 2 years ago

Thanks for running those tests—they're very helpful details. It's odd though that the skulpin/rafx library used for rendering to a window has no trouble working with the Skia backend-context but the ash-based code for offscreen rendering is failing.

@lucasmerlin: do you have any guesses as to why the DirectContext::new_vulkan call would succeed but then fail when it's used for a subsequent Surface::new_render_target? I guessed that it might have been sRGB colorspace-related but disabling that in rc2 doesn't seem to have changed anything.

lucasmerlin commented 2 years ago

do you have any guesses as to why the DirectContext::new_vulkan call would succeed but then fail when it's used for a subsequent Surface::new_render_target?

That is weird, I have always been able to create a Surface if DirectContext creation was successful. The only time I had problems creating new gpu surfaces was when I had threading issues, but that made the program crash with a segfault.

Maybe some Vulkan features are missing that are required for skia? Would be interesting to see if other software using skia and vulkan runs on that gpu.

@mikhailsdv can you share the output of chrome://gpu/ on your device? It should show vulkan: disabled or enabled if it's disabled you should be able to enable it in chrome://flags and see if chrome still works.

mpaperno commented 2 years ago

FWIW, similar/same issue here on one of my "little computers."

On my main dev box running with NVIDIA GPU and SC v1.0.0 was good (and rendering bitmaps on GPU is fast!).

Tried to run same (console-based, TypeScript) app on a test box with Intel Graphics and got crash with Error: Could not allocate new 200x200 bitmap when creating a new Canvas. Found this Issue, installed rc2, now no crash (yay!). But Canvas.gpu reports false on this box.

Test box is an Intel NUC-something, Core i3-6100U, Intel Graphics 520.... see screenshot image for driver details. Just installed latest Intel driver. Reports "Vulkan 1.3.215".

Chrome's chrome://gpu page initially reported false for Vulkan support. I changed the flag in chrome://flags as suggested by @lucasmerlin and it now reports true and still runs fine. (TBH I may have disabled hardware accel. in this Chrome at some point... dunno if that changes the Vulkan flag or not, but changing it to true re-enabled all the HW support features.)

Attached is Chrome's "gpu" report and screenshot of some basic graphics driver info. LMK if there's anything else that may be helpful. (I'm connected via RDP so the "remote display" will also show up as a driver in the gpu report.)

Thanks, -Max

intel-nuc-IHDG520-chrome-gpu-report.txt intel-nuc-IHDG520-driver-info.jpg

mikhailsdv commented 2 years ago

Snipaste_2022-09-08_02-16-36

@mpaperno here is my chrome://gpu output. You can preview «Graphics Feature Status» on the screenshot. Initially, Vulkan was disabled. After enabling it, Chrome still works file.

chrome_gpu_page.zip

mikhailsdv commented 2 years ago

UPD: After enabling it, Chrome unable to play any video.