-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Enhancement limit WebGL textures to gl.MAX_TEXTURE_SIZE #6651
Enhancement limit WebGL textures to gl.MAX_TEXTURE_SIZE #6651
Conversation
… enhancement/limit-textures
Hi @davepagurek, Here's the problem:
Is there something I might have overlooked or misunderstood in this context? Any insights on what might be causing this behaviour? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oddly, the error doesn't occur when only one dimension is limited to 8192 and the other is kept below 4000.
I think this SO answer's explanation also applies here: basically, gl.MAX_TEXTURE_SIZE
is definitely the max that can be supported in any dimension, but it doesn't make any guarantees that you have enough memory to store MAX x MAX textures, or even if you can store one, that you can store a second, if you choose to make it.
Do you run into issues with framebuffers only when the main canvas is also really big? Or do they work if you have a tiny main canvas but a big framebuffer? If it's the latter, it sounds like maybe it's running into a memory limit.
In any case, I think we won't be able to prevent all context losses when trying to make a large texture, but I think the checks being done here are a helpful start!
src/core/p5.Graphics.js
Outdated
maxTextureSize / this._pixelDensity | ||
); | ||
w = Math.min(w, maxAllowedPixelDimensions); | ||
h = Math.min(h, maxAllowedPixelDimensions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to log a warning here (and in p5.Framebuffer.js) if the width/height we end up picking is different than what the user requested.
src/core/p5.Graphics.js
Outdated
const gl = this._renderer.GL; | ||
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); | ||
const maxAllowedPixelDimensions = Math.floor( | ||
maxTextureSize / this._pixelDensity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, this depends on the density. I think this means that we may need to do a similar check when the user sets pixelDensity() too for complete coverage
@@ -60,6 +60,13 @@ p5.Graphics = class extends p5.Element { | |||
|
|||
if (r === constants.WEBGL) { | |||
this._renderer = new p5.RendererGL(this.canvas, this, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want this for both graphics and the main canvas, so maybe we should do the check inside RendererGL instead?
src/core/p5.Graphics.js
Outdated
@@ -60,6 +60,13 @@ p5.Graphics = class extends p5.Element { | |||
|
|||
if (r === constants.WEBGL) { | |||
this._renderer = new p5.RendererGL(this.canvas, this, false); | |||
const gl = this._renderer.GL; | |||
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This theoretically shouldn't change over time, so maybe we can add a method to RendererGL to be something like this:
maxTextureSize() {
if (!this._maxTextureSize) {
this._maxTextureSize = this.GL.getParameter(this.GL.MAX_TEXTURE_SIZE);
}
return this._maxTextureSize;
}
getParameter
calls are generally a bit slow, so we want to cache their results (or avoid calling them if there's a convenient way to do so.)
…blin/p5.js into enhancement/limit-textures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes so far! I think the remaining changes would be:
- can we also handle this in
resizeCanvas
(for the main canvas andp5.Graphics) and
resize(for
p5.Framebuffer`)? - can we add some unit tests for this? You can use
sinon.stub(object, "method", func);
to replace a system function with another function for easier testing (e.g. used here). Maybe you could use that to mock a specific max texture size (even like 100, just for testing) and make assertions on other things working accordingly
Hi @davepagurek, I have spent significant time in debugging this. Strangely, I encountered a completely different error when running npm test, and after pushing the code, yet another error emerged. |
test/unit/core/rendering.js
Outdated
myp5.createCanvas(10, 10, myp5.WEBGL); | ||
myp5.resizeCanvas(200, 200); | ||
assert.equal(myp5.canvas.width, 100); | ||
assert.equal(myp5.canvas.height, 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think myp5.width
and myp5.height
should also be 100 here? I think currently they aren't because we set this.width
and this.height
before adjusting the sizes, but I'm not sure just yet what the expected result would be. I think I lean towards having those values also be 100 for consistency, what do you think?
Looks like some of the tests are failing. It might be that in the test environment on CI, the max texture size is something unexpected. Does the same thing happen when you run |
Sorry forgot to add comment during the previous commit, after updating Now, this commit uses glStub.restore() inside afterEach(), tests passed. But why does this happen? P.S. I just tried glStub.restore() inside the test("it resizes the graphics based on max texture size") in p5.Graphics, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly not totally sure why doing it per-test doesn't work but doing it in an afterEach
does. I'm glad you were able to find a fix though!
I think this is good to go now! Since we've started our release process with a beta build, I'm going to hold off on merging this until after we finish the release so that we don't accidentally introduce new bugs during the testing period. I'll merge this right after that though!
Looks great! Thanks @capGoblin and @davepagurek! |
Resolves #6546
Changes:
For both Graphics and Framebuffer
Screenshots of the change:
PR Checklist
npm run lint
passes