Skip to content

Commit

Permalink
Add an optional desynchronized mode to 2D canvas
Browse files Browse the repository at this point in the history
Developers of stylus-based drawing applications (e.g., Google Keep) have found this hint to be critical in order to be competitive with native applications. It has been prototyped in Chromium and yields significant latency improvements there.

Tests: will be added as part of https://bugs.chromium.org/p/chromium/issues/detail?id=788439.

Supersedes #4234. Partial fix for #4087.

Co-authored-by: Miguel Casas-Sanchez <mcasas@chromium.org>
  • Loading branch information
2 people authored and annevk committed Mar 20, 2019
1 parent e32a6f8 commit cf529a3
Showing 1 changed file with 64 additions and 32 deletions.
96 changes: 64 additions & 32 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -60200,6 +60200,7 @@ enum <dfn>CanvasFillRule</dfn> { "<span data-x="dom-context-2d-fillRule-nonzero"

dictionary <dfn>CanvasRenderingContext2DSettings</dfn> {
boolean <span data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</span> = true;
boolean <span data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</span> = false;
};

enum <dfn>ImageSmoothingQuality</dfn> { "<span data-x="dom-context-2d-imageSmoothingQuality-low">low</span>", "<span data-x="dom-context-2d-imageSmoothingQuality-medium">medium</span>", "<span data-x="dom-context-2d-imageSmoothingQuality-high">high</span>" };
Expand Down Expand Up @@ -60452,36 +60453,38 @@ interface <dfn>Path2D</dfn> {
objects.</p>

<dl class="domintro">

<dt><var>context</var> = <var>canvas</var> . <code data-x="dom-canvas-getContext">getContext</code>('2d' [, { [ <code data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code>: false ] } ] )</dt>

<dt><var>context</var> = <var>canvas</var> . <code data-x="dom-canvas-getContext">getContext</code>('2d' [, { [ <code data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code>: true ] [, <code data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</code>: false ] } ] )</dt>
<dd>

<p>Returns a <code>CanvasRenderingContext2D</code> object that is permanently bound to a
particular <code>canvas</code> element.</p>

<p>If the <code data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code> setting is
provided and set to false, then the canvas is forced to always be opaque.</p>
<p>If the <code data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code> member is
false, then the context is forced to always be opaque.</p>

<p>If the <code
data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</code> member is
true, then the context might be <span
data-x="concept-canvas-desynchronized">desynchronized</span>.</p>
</dd>

<dt><var>context</var> . <code subdfn data-x="dom-context-2d-canvas">canvas</code></dt>

<dd>

<p>Returns the <code>canvas</code> element.</p>

</dd>

<dt><var>attributes</var> = <var>canvas</var> . <code data-x="dom-context-2d-canvas-getcontextattributes">getContextAttributes</code>()</dt>

<dd>
<p>Returns an object whose:</p>

<p>Returns an object whose <code data-x="concept-canvas-alpha">alpha</code> member is true if
the context has an alpha channel, or false if it was forced to be opaque.</p>
<ul>
<li><code data-x="concept-canvas-alpha">alpha</code> member is true if the context has an alpha
channel, or false if it was forced to be opaque.</li>

<li><code data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</code>
member is true if the context can be <span
data-x="concept-canvas-desynchronized">desynchronized</span>.</li>
</ul>
</dd>

</dl>

<div w-nodev>
Expand All @@ -60497,12 +60500,11 @@ interface <dfn>Path2D</dfn> {
<!--REMOVE-TOPIC:Security-->

<p>The <code>CanvasRenderingContext2D</code> object also has an <dfn
data-x="concept-canvas-alpha">alpha</dfn> flag, which can be set to true or false. Initially,
when the context is created, its <span data-x="concept-canvas-alpha">alpha</span> flag must be
set to true. When a <code>CanvasRenderingContext2D</code> object has its <span
data-x="concept-canvas-alpha">alpha</span> flag set to false, then its alpha channel must be
fixed to 1.0 (fully opaque) for all pixels, and attempts to change the alpha component of any
pixel must be silently ignored.</p>
data-x="concept-canvas-alpha">alpha</dfn> boolean. When a
<code>CanvasRenderingContext2D</code> object's <span
data-x="concept-canvas-alpha">alpha</span> is false, then its alpha channel must be fixed to 1.0
(fully opaque) for all pixels, and attempts to change the alpha component of any pixel must be
silently ignored.</p>

<p class="note">Thus, the bitmap of such a context starts off as <span>opaque black</span> instead
of <span>transparent black</span>; <code data-x="dom-context-2d-clearRect">clearRect()</code>
Expand All @@ -60512,14 +60514,43 @@ interface <dfn>Path2D</dfn> {
fourth byte in its input, and so on. However, the alpha component of styles and images drawn
onto the canvas are still honoured up to the point where they would impact the <span>output
bitmap</span>'s alpha channel; for instance, drawing a 50% transparent white square on a freshly
created <span>output bitmap</span> with its <span data-x="concept-canvas-alpha">alpha</span>
flag set to false will result in a fully-opaque gray square.</p>
created <span>output bitmap</span> with its <span data-x="concept-canvas-alpha">alpha</span> set
to false will result in a fully-opaque gray square.</p>

<p>The <code>CanvasRenderingContext2D</code> object also has a <dfn
data-x="concept-canvas-desynchronized">desynchronized</dfn> boolean. When a
<code>CanvasRenderingContext2D</code> object's <span
data-x="concept-canvas-desynchronized">desynchronized</span> is true, then the user agent may
optimize the rendering of the canvas to reduce the latency, as measured from input events to
rasterization, by desynchronizing the canvas paint cycle from the event loop, bypassing the
ordinary user agent rendering algorithm, or both. Insofar as this mode involves bypassing the
usual paint mechanisms, rasterization, or both, it might introduce visible tearing artifacts.</p>

<p class="note">The user agent usually renders on a buffer which is not being displayed, quickly
swapping it and the one being scanned out for presentation; the former buffer is called
back buffer and the latter <i>front buffer</i>. A popular technique for reducing latency is called
front buffer rendering, also known as <i>single buffer</i> rendering, where rendering happens in
parallel and racily with the scanning out process. This technique reduces the latency at the price
of potentially introducing tearing artifacts and can be used to implement in total or part of the
<span data-x="concept-canvas-desynchronized">desynchronized</span> boolean. <ref
spec=MULTIPLEBUFFERING></p>

<p class="note">The <span data-x="concept-canvas-desynchronized">desynchronized</span> boolean
can be useful when implementing certain kinds of applications, such as drawing applications,
where the latency between input and rasterization is critical.</p>

<p>The <dfn><code
data-x="dom-context-2d-canvas-getcontextattributes">getContextAttributes()</code></dfn> method,
when invoked, must return a <code>CanvasRenderingContext2DSettings</code> dictionary whose <code
data-x="concept-canvas-alpha">alpha</code> member is set to true if this context's <span
data-x="concept-canvas-alpha">alpha</span> flag is set, and false otherwise.</p>
when invoked, must return a <code>CanvasRenderingContext2DSettings</code> dictionary containing
the following members:</p>

<ul>
<li><p><code data-x="concept-canvas-alpha">alpha</code>, set to this context's <span
data-x="concept-canvas-alpha">alpha</span>.</p></li>

<li><p><code data-x="concept-canvas-desynchronized">desynchronized</code>, set to this context's
<span data-x="concept-canvas-desynchronized">desynchronized</span>.</p></li>
</ul>

<hr>

Expand Down Expand Up @@ -60575,15 +60606,13 @@ interface <dfn>Path2D</dfn> {
data-x="attr-canvas-width">width</code> and <code data-x="attr-canvas-height">height</code>
content attributes.</p></li>

<li>
<p>Process each of the members of <var>settings</var> as follows:</p>
<li><p>Set <var>context</var>'s <span data-x="concept-canvas-alpha">alpha</span> to
<var>settings</var>'s <dfn><code
data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code></dfn>.</p></li>

<dl>
<dt><dfn><code data-x="dom-CanvasRenderingContext2DSettings-alpha">alpha</code></dfn></dt>
<dd>If false, then set <var>context</var>'s <span data-x="concept-canvas-alpha">alpha</span>
flag to false.</dd>
</dl>
</li>
<li><p>Set <var>context</var>'s <span
data-x="concept-canvas-desynchronized">desynchronized</span> to <var>settings</var>'s <dfn><code
data-x="dom-CanvasRenderingContext2DSettings-desynchronized">desynchronized</code></dfn>.</p></li>

<li><p>Return <var>context</var>.</p></li>
</ol>
Expand Down Expand Up @@ -121910,6 +121939,9 @@ INSERT INTERFACES HERE
<dt id="refsMQ">[MQ]</dt>
<dd><cite><a href="https://drafts.csswg.org/mediaqueries/">Media Queries</a></cite>, H. Lie, T. &Ccedil;elik, D. Glazman, A. van Kesteren. W3C.</dd>

<dt id="refsMULTIPLEBUFFERING">[MULTIPLEBUFFERING]</dt>
<dd>(Non-normative) <cite><a href="https://en.wikipedia.org/wiki/Multiple_buffering">Multiple buffering</a></cite>. Wikipedia.</dd>

<dt id="refsNAVMODEL">[NAVMODEL]</dt>
<dd><cite><a href="https://arxiv.org/abs/1608.05444">A Model of Navigation History</a></cite>. C. Brewster, A. Jeffrey.</dd>

Expand Down

0 comments on commit cf529a3

Please sign in to comment.