processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs ā€”
http://p5js.org/
GNU Lesser General Public License v2.1
21.54k stars 3.3k forks source link

[p5.js 2.0 RFC Proposal]: Allow access to context attributes in renderers #6781

Open dhowe opened 8 months ago

dhowe commented 8 months ago

Increasing access

This allows users to access a fuller set of options for rendering to the canvas

Which types of changes would be made?

Most appropriate sub-area of p5.js?

What's the problem?

Current renderers do not give access to the full feature set for rendering to the canvas, specifically (for the '2d 'context) the following options:

alpha

A boolean value that indicates if the canvas contains an alpha channel. If set to false, the browser now knows that the backdrop is always opaque, which can speed up drawing of transparent content and images.

colorSpace Optional

Specifies the color space of the rendering context. Possible values are:

    "srgb" selects the [sRGB color space](https://en.wikipedia.org/wiki/SRGB). This is the default value.
    "display-p3" selects the [display-p3 color space](https://en.wikipedia.org/wiki/DCI-P3).

desynchronized

A boolean value that hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop

willReadFrequently

A boolean value that indicates whether or not a lot of read-back operations are planned. This will force the use of a software (instead of hardware accelerated) 2D canvas and can save memory when calling getImageData() frequently.

There is a still larger set for the WebGL context here

What's the solution?

Allow an object holding canvasContext options to be passed into createCanvas, as an optional parameter. When these are passed to the Renderer's constructor they can be used in the canvas.getContext() call. This is relatively simple to implement in the current code base and would cause no compatibility issues.

Pros (updated based on community comments)

Example list:

Cons (updated based on community comments)

None

Proposal status

Under review

davepagurek commented 8 months ago

For synchronized and willReadFrequently: We have setAttributes for WebGL contexts already where users can set some of those if they want. Would extending that to also work on 2D canvases suffice?

For alpha: how do you feel about this proposal? https://github.com/processing/p5.js/issues/6756

For colorSpace: this will definitely be a goal of 2.0 and is present in the RFC currently. It would be great to iron out the implementation details though! Both 2D canvas and WebGL support display-p3 now on Chrome, via different APIs (attributes to the getContext() call for 2D, via the drawingBufferColorSpace and unpackColorSpace properties for WebGL.) Firefox doesn't support it yet. I think we may want to design any color settings to be able to gracefully degrade to srgb if used on a browser that doesn't support these yet. @limzykenneth, did you have some initial thoughts on how to go about the color refactor?

dhowe commented 8 months ago

For synchronized and willReadFrequently: We have setAttributes for WebGL contexts already where users can set some of those if they want. Would extending that to also work on 2D canvases suffice?

These were my main concern here, so that would totally work for me

But for alpha, being able to specify false for opaque contexts should give a performance boost (I haven't benchmarked to know how much), and is not, as best I can tell, addressed in #6756

davepagurek commented 8 months ago

Ah sorry I thought by alpha you meant something that maps to globalAlpha on CanvasRenderingContext2D. We actually already support the alpha attribute in WebGL via setAttributes šŸ™‚

limzykenneth commented 8 months ago

I'm not sure the Color module rewrite proposal will overlap with the color space setting here. What I'm thinking about in terms of new Color module is to make it more or less compatible with CSS colors and where sensible draw additional inspiration/ideas from color.js.

For the canvas color space we can possibly change the default to p3 and fallback to srgb with something like this line.

const colorSpace = window.matchMedia('(color-gamut: p3)').matches ? 'display-p3' : 'srgb';

And createCanvas possibly accepting additional options argument in the form of createCanvas(400, 400, WEBGL, {colorGamut: "display-p3"}) and/or any of the required ones. The actual implementation should be done in individual renderers (ie. Renderer2D, RendererGL) instead of the base Renderer class. This way, further extending to other renderers that may want different options can be accommodated in the future without changing the API.

Qianqianye commented 7 months ago

Thanks @dhowe for making the proposal. To better organize the proposals, could you add a title to this issue? Thanks.