Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Best way to manage a buffer #774

Closed
lbittner-pdftron opened this issue Aug 19, 2019 · 4 comments
Closed

[Question] Best way to manage a buffer #774

lbittner-pdftron opened this issue Aug 19, 2019 · 4 comments

Comments

@lbittner-pdftron
Copy link

Hello!

I'm pretty new to Web Assembly and managing memory and just wanted to ask what the best way to manage this scenario is.

My module will be processing pixels in a Uint8ClampedArray (from a canvas).

Right now my set up is as follows (which is working great):

// wasm
allocateMemory(length: i32): Uint8Array {
    return new Uint8Array(length);
}

renderWASM(pointer: usize) {
    // process data in buffer
}

// js
renderJS() {
   let jsArray = [...]; // data from canvas
   let pointer = module.allocateMemory(length);
   let wasmArray = new Uint8ClampedArray(module.memory.buffer, pointer, jsArray.length);
   wasmArray.set(jsArray);
   module.renderWASM(pointer)
  // should i destory the buffer here?
}

My issue is that renderJS() will be called multiple times throughout the lifecycle, but each time the canvas will probably be a different size and have a different amount of pixels, meaning the buffer length would have to change.

In this scenario, should I be destroying the buffer and recreating it each render? Or is there a better way to do this?

Thanks so much for the help, i've been having a lot of fun using this project and am learning a lot.

@willemneal
Copy link
Contributor

willemneal commented Aug 19, 2019

@jtenner made: https://github.com/as2d/as2d, so he'd be the better one to answer this. But the big take away from his solution to this problem was to queue up mutations and then flush them all at once.

Here is his article about it: https://dev.to/jtenner/optimizing-canvasrenderingcontext2d-function-calls-using-assemblyscript-4i4b

Glad to hear things are going well so far!

@lbittner-pdftron
Copy link
Author

Thanks for the links!

Im not too concerned about how fast the render methods will be called so I don't think a queue will be necessary for my use case yet. I'm more concerned about managing a buffer that will be changing in size each time its used (and not knowing how large it could get).

I think for now I will just keep the buffer around and increase the size as needed.

Thanks again!

@dcodeIO
Copy link
Member

dcodeIO commented Aug 19, 2019

This doesn't look like it will work btw:

   let pointer = module.allocateMemory(length);
   let wasmArray = new Uint8ClampedArray(module.memory.buffer, pointer, jsArray.length);
   wasmArray.set(jsArray);

Here, pointer points at the Uint8Array header (see), not the backing buffer with the data, so the .set would corrupt memory.

Other than that, the most efficient way to work with explicitly resize-able memory segments is using __alloc, __realloc and __free directly. Even better would be to use a --memoryBase (see) with some reasonable maximum to also avoid resizing.

@lbittner-pdftron
Copy link
Author

Thanks @dcodeIO. I was following examples from this issue and never released the pointer was pointing to something else. Everything seems to be working with my current implementation though.

Ill try playing around with __alloc and those functions. Thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants