Skip to content

Commit

Permalink
Add CanvasColorType, with unorm8 and float16 support
Browse files Browse the repository at this point in the history
The default behavior is unorm8, which matches the existing behavior of all user agents.

The name unorm8 is chosen to match modern APIs which distinguish between 8-bit unsigned normalized and 8-bit unsigned integer (e.g, VK_FORMAT_R8G8B8A8_UNORM vs VK_FORMAT_R8G8B8A8_UINT in Vulkan, MTLPixelFormatRGBA8Unorm vs MTLPixelFormatRGBA8Uint in Metal, and "rgba8unorm" vs "rgba8uint" in WebGPU).

The use of colorType (instead of pixelFormat) is used to avoid the complexity of selecting channel ordering (BGRA vs RGBA) and interactions with the alpha parameter (RGB, RGBX, or BGRX potentially being required if alpha is false).
  • Loading branch information
ccameron-chromium authored Feb 10, 2025
1 parent 972b0c4 commit a5853ca
Showing 1 changed file with 49 additions and 3 deletions.
52 changes: 49 additions & 3 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -65378,12 +65378,15 @@ typedef (<span>HTMLOrSVGImageElement</span> or

enum <dfn enum>PredefinedColorSpace</dfn> { "<span data-x="dom-PredefinedColorSpace-srgb">srgb</span>", "<span data-x="dom-PredefinedColorSpace-display-p3">display-p3</span>" };

enum <dfn enum>CanvasColorType</dfn> { "<span data-x="dom-CanvasColorType-unorm8">unorm8</span>", "<span data-x="dom-CanvasColorType-float16">float16</span>" };

enum <dfn enum>CanvasFillRule</dfn> { "<span data-x="dom-context-2d-fillRule-nonzero">nonzero</span>", "<span data-x="dom-context-2d-fillRule-evenodd">evenodd</span>" };

dictionary <dfn dictionary>CanvasRenderingContext2DSettings</dfn> {
boolean <span data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</span> = true;
boolean <span data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</span> = false;
<span>PredefinedColorSpace</span> <span data-x="dom-CanvasRenderingContext2DSettings-colorSpace">colorSpace</span> = "<span data-x="dom-PredefinedColorSpace-srgb">srgb</span>";
<span>CanvasColorType</span> <span data-x="dom-CanvasRenderingContext2DSettings-colorType">colorType</span> = "<span data-x="dom-CanvasColorType-unorm8">unorm8</span>";
boolean <span data-x="dom-CanvasRenderingContext2DSettings-willReadFrequently">willReadFrequently</span> = false;
};

Expand Down Expand Up @@ -65675,6 +65678,10 @@ interface <dfn interface>Path2D</dfn> {
specifies the <span data-x="concept-canvas-color-space">color space</span> of the rendering
context.</p>

<p>The <code data-x="dom-CanvasRenderingContext2DSettings-colorType">colorType</code> member
specifies the <span data-x="concept-canvas-color-type">color type</span> of the rendering
context.</p>

<p>If the <code
data-x="dom-CanvasRenderingContext2DSettings-willReadFrequently">willReadFrequently</code>
member is true, then the context is marked for <span
Expand All @@ -65699,6 +65706,10 @@ interface <dfn interface>Path2D</dfn> {
a string indicating the context's <span data-x="concept-canvas-color-space">color
space</span>.</li>

<li><code data-x="dom-CanvasRenderingContext2DSettings-colorType">colorType</code> member is
a string indicating the context's <span data-x="concept-canvas-color-type">color
type</span>.</li>

<li><code data-x="dom-CanvasRenderingContext2DSettings-willReadFrequently">willReadFrequently</code>
member is true if the context is marked for <span data-x="concept-canvas-will-read-frequently">readback
optimization</span>.</li>
Expand Down Expand Up @@ -65832,6 +65843,19 @@ context.fillRect(100,0,50,50); // only this square remains</code></pre>

<hr>

<p>The <code>CanvasColorType</code> enumeration is used to specify the <span
data-x="concept-canvas-color-type">color type</span> of the canvas's backing store.</p>

<p>The "<dfn enum-value for="CanvasColorType"><code
data-x="dom-CanvasColorType-unorm8">unorm8</code></dfn>" value indicates that the type
for all color channels is 8-bit unsigned normalized.</p>

<p>The "<dfn enum-value for="CanvasColorType"><code
data-x="dom-CanvasColorType-float16">float16</code></dfn>" value indicates that the type
for all color channels is 16-bit floating point.</p>

<hr>

<p>The <code>CanvasFillRule</code> enumeration is used to select the <dfn>fill rule</dfn>
algorithm by which to determine if a point is inside or outside a path.</p>

Expand Down Expand Up @@ -65974,6 +65998,12 @@ context.fillRect(100,0,50,50); // only this square remains</code></pre>
data-x="concept-canvas-color-space">color space</span> indicates the color space for the
<span>output bitmap</span>.</p>

<p>The <code>CanvasSettings</code> object also has a <dfn
data-x="concept-canvas-color-type">color type</dfn> setting of type
<code>CanvasColorType</code>. The <code>CanvasSettings</code> object's <span
data-x="concept-canvas-color-type">color type</span> indicates the data type of the
color and alpha components of the pixels of the <span>output bitmap</span>.</p>

<p>To <dfn data-x="canvas-setting-init-bitmap">initialize a <code>CanvasSettings</code> output
bitmap</dfn>, given a <code>CanvasSettings</code> <var>context</var> and a
<code>CanvasRenderingContext2DSettings</code> <var>settings</var>:</p>
Expand All @@ -65992,6 +66022,10 @@ context.fillRect(100,0,50,50); // only this square remains</code></pre>
<var>settings</var>["<dfn dict-member for="CanvasRenderingContext2DSettings"><code
data-x="dom-CanvasRenderingContext2DSettings-colorSpace">colorSpace</code></dfn>"].</p></li>

<li><p>Set <var>context</var>'s <span data-x="concept-canvas-color-type">color type</span> to
<var>settings</var>["<dfn dict-member for="CanvasRenderingContext2DSettings"><code
data-x="dom-CanvasRenderingContext2DSettings-colorType">colorType</code></dfn>"].</p></li>

<li><p>Set <var>context</var>'s <span data-x="concept-canvas-will-read-frequently">will read
frequently</span> to <var>settings</var>["<dfn dict-member
for="CanvasRenderingContext2DSettings"><code
Expand All @@ -66006,6 +66040,8 @@ context.fillRect(100,0,50,50); // only this square remains</code></pre>
<span>this</span>'s <span data-x="concept-canvas-desynchronized">desynchronized</span>, "<code
data-x="dom-CanvasRenderingContext2DSettings-colorSpace">colorSpace</code>" → <span>this</span>'s
<span data-x="concept-canvas-color-space">color space</span>, "<code
data-x="dom-CanvasRenderingContext2DSettings-colorType">colorType</code>" → <span>this</span>'s
<span data-x="concept-canvas-color-type">color type</span>, "<code
data-x="dom-CanvasRenderingContext2DSettings-willReadFrequently">willReadFrequently</code>" →
<span>this</span>'s <span data-x="concept-canvas-will-read-frequently">will read frequently</span>
]».</p>
Expand Down Expand Up @@ -71844,6 +71880,16 @@ interface <dfn interface>OffscreenCanvasRenderingContext2D</dfn> {
data-x="dom-canvas-toBlob">toBlob()</code> method to the canvas, given the appropriate dimensions,
has no visible effect beyond, at most, clipping colors of the canvas to a more narrow gamut.</p>

<p>For image types that support multiple bit depths, the serialized image must use the bit depth
that best preserves content of the underlying bitmap.</p>

<p class="example">For example, when serializing a 2D context that has
<span data-x="concept-canvas-color-type">color type</span> of
<span data-x="dom-CanvasColorType-float16">float16</span> to <var>type</var>
"<code>image/png</code>", the resulting image would have 16 bits per sample.
This serialization will still lose significant detail (all values less than 0.5/65535
would be clamped to 0, and all values greater than 1 would be clamped to 1).</p>

<p>If <var>type</var> is an image format that supports variable quality (such as
"<code>image/jpeg</code>"), <var>quality</var> is given, and <var>type</var> is not
"<code>image/png</code>", then, if <var>quality</var> <span data-x="js-Number">is a Number</span>
Expand Down Expand Up @@ -71983,9 +72029,9 @@ interface <dfn interface>OffscreenCanvasRenderingContext2D</dfn> {
<p>As certain colors can only be represented under premultiplied alpha (for instance, additive
colors), and others can only be represented under non-premultiplied alpha (for instance,
"invisible" colors which hold certain red, green, and blue values even with no opacity); and
division and multiplication on 8-bit integers (which is how canvas's colors are currently stored)
entails a loss of precision, converting between premultiplied and non-premultiplied alpha is a
lossy operation on colors that are not fully opaque.</p>
division and multiplication using finite precision entails a loss of accuracy, converting between
premultiplied and non-premultiplied alpha is a lossy operation on colors that are not fully
opaque.</p>

<p>A <code>CanvasRenderingContext2D</code>'s <span>output bitmap</span> and an
<code>OffscreenCanvasRenderingContext2D</code>'s <span>output bitmap</span> must use premultiplied
Expand Down

0 comments on commit a5853ca

Please sign in to comment.