Skip to content

Commit

Permalink
Make ImageBitmap transferable
Browse files Browse the repository at this point in the history
ImageBitmap objects can already be sent using postMessage(), but this
requires a duplication of the bitmap data in memory, which is
inefficient and often unnecessary. This change is a pre-requisite
for the OffscreenCanvas proposal, which relies on ImageBitmaps as
an efficient means of transferring bitmap data to and from Workers.
See: https://wiki.whatwg.org/wiki/OffscreenCanvas
  • Loading branch information
junov authored and annevk committed Jan 15, 2016
1 parent 8558f93 commit 334f9ed
Showing 1 changed file with 86 additions and 32 deletions.
118 changes: 86 additions & 32 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -7649,13 +7649,17 @@ interface <dfn>DOMStringMap</dfn> {
<li><code data-x="idl-ArrayBuffer">ArrayBuffer</code>
<li><code>CanvasProxy</code> (defined in this specification)
<li><code>MessagePort</code> (defined in this specification)
<li><code>ImageBitmap</code> (defined in this specification)
</ul>

<div w-nodev>

<p>The following IDL block formalizes this:</p>

<pre class="idl">typedef (<span>ArrayBuffer</span> or <span>CanvasProxy</span> or <span>MessagePort</span>) <dfn>Transferable</dfn>;</pre>
<pre class="idl">typedef (<span>ArrayBuffer</span>
or <span>CanvasProxy</span>
or <span>MessagePort</span>
or <span>ImageBitmap</span>) <dfn>Transferable</dfn>;</pre>

<p>To <dfn>transfer a <code>Transferable</code> object</dfn> to a new owner, the user agent must
run the steps defined for the type of object in question. The steps will return a new object of
Expand Down Expand Up @@ -7786,8 +7790,15 @@ interface <dfn>DOMStringMap</dfn> {

<dt>If <var>input</var> is an <code>ImageBitmap</code> object</dt>

<dd><p>Let <var>output</var> be a newly constructed <code>ImageBitmap</code> object whose
bitmap data is a copy of <var>input</var>'s bitmap data.</p></dd>
<dd><p>If <var>input</var> has been <span
data-x="concept-Transferable-neutered">neutered</span>, throw a <code>DataCloneError</code>
exception and abort the overall <span>structured clone</span> algorithm. Otherwise, let
<var>output</var> be a newly constructed <code>ImageBitmap</code> object whose
<span data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> is a copy of
<var>input</var>'s <span data-x="concept-ImageBitmap-bitmap-data">bitmap data</span>, and
whose <span data-x="concept-canvas-origin-clean">origin-clean</span> flag is set to the same
value as <var>input</var>'s <span data-x="concept-canvas-origin-clean">origin-clean</span>
flag.</p></dd>

<dt>If <var>input</var> is an <code data-x="idl-ArrayBuffer">ArrayBuffer</code> object</dt>

Expand Down Expand Up @@ -90763,6 +90774,7 @@ interface <dfn>ImageBitmap</dfn> {
readonly attribute unsigned long <span data-x="dom-ImageBitmap-width">width</span>;
readonly attribute unsigned long <span data-x="dom-ImageBitmap-height">height</span>;
};
<span>ImageBitmap</span> implements <span>Transferable</span>;

typedef (<span>HTMLImageElement</span> or
<span>HTMLVideoElement</span> or
Expand Down Expand Up @@ -90807,15 +90819,19 @@ interface <dfn>ImageBitmapFactories</dfn> {
any pixels missing in the original replaced by transparent black. These coordinates are in the
source image's pixel coordinate space, <em>not</em> in CSS pixels.</p>

<p>Rejects the promise with an <code>InvalidStateError</code> exception if the source image is not in a valid
state (e.g. an <code>img</code> element that hasn't finished loading, or a
<code>CanvasRenderingContext2D</code> object whose bitmap data has zero length along one or both
dimensions, or an <code>ImageData</code> object whose data is <code
data-x="dom-imagedata-data">data</code> attribute has been <span
data-x="concept-Transferable-neutered">neutered</span>). Rejects the promise with a <code>SecurityError</code>
exception if the script is not allowed to access the image data of the source image (e.g. a
<code>video</code> that is <span>CORS-cross-origin</span>, or a <code>canvas</code> being drawn
on by a script in a worker from another <span>origin</span>).</p>
<p>Rejects the promise with an <code>InvalidStateError</code> exception if the source image is
not in a valid state (e.g. an <code>img</code> element that hasn't finished loading, or a
<code>CanvasRenderingContext2D</code> object whose bitmap data has zero length along one or
both dimensions, an ImageBitmap object that has been <span
data-x="concept-Transferable-neutered">neutered</span>, or an <code>ImageData</code> object
whose data is <code data-x="dom-imagedata-data">data</code> attribute has been <span
data-x="concept-Transferable-neutered">neutered</span>).</p>

<p>Rejects the promise with a
<code>SecurityError</code> exception if the script is not allowed to access the image data of
the source image (e.g. a <code>video</code> that is <span>CORS-cross-origin</span>, or a
<code>canvas</code> being drawn on by a script in a worker from another
<span>origin</span>).</p>

</dd>

Expand All @@ -90839,9 +90855,10 @@ interface <dfn>ImageBitmapFactories</dfn> {

<div w-nodev>

<p>An <code>ImageBitmap</code> object always has associated bitmap data, with a width and a
height. However, it is possible for this data to be corrupted. If an <code>ImageBitmap</code>
object's media data can be decoded without errors, it is said to be <dfn
<p>An <code>ImageBitmap</code> object always has associated <dfn
data-x="concept-ImageBitmap-bitmap-data">bitmap data</dfn>, with a width and a height. However,
it is possible for this data to be corrupted. If an <code>ImageBitmap</code> object's media data
can be decoded without errors, it is said to be <dfn
data-x="concept-ImageBitmap-good">fully decodable</dfn>.</p>

<p>An <code>ImageBitmap</code> object's bitmap has an <span
Expand All @@ -90850,6 +90867,26 @@ interface <dfn>ImageBitmapFactories</dfn> {
true and may be changed to false by the steps of <code
data-x="dom-createImageBitmap">createImageBitmap()</code>.</p>

<p>To <span data-x="transfer a Transferable object">transfer</span> an <code>ImageBitmap</code>
object <var>old</var> to a new owner <var>owner</var>, a user agent must run the following
steps:</p>

<ol>
<li><p>Create a new <code>ImageBitmap</code> object pointing at the same underlying <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> as <var>old</var>, thus obtaining
<var>new</var>;</p></li>

<li><p>Set <var>new</var>'s bitmap's <span
data-x="concept-canvas-origin-clean">origin-clean</span> flag to the same values as
<var>old</var>'s bitmap's <span data-x="concept-canvas-origin-clean">origin-clean</span>
flag;</p></li>

<li><p><span data-x="concept-Transferable-neutered">Neuter</span> the <var>old</var>
object;</p></li>

<li><p>Return <var>new</var>.</p></li>
</ol>

<p>An <code>ImageBitmap</code> object can be obtained from a variety of different objects, using
the <dfn><code data-x="dom-createImageBitmap">createImageBitmap()</code></dfn> method. When
invoked, the method must act as follows:</p>
Expand All @@ -90876,11 +90913,13 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be a copy of the <code>img</code>
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be a copy of the <code>img</code>
element's media data, <span>cropped to the source rectangle</span>. If this is an animated
image, the <code>ImageBitmap</code> object's bitmap data must only be taken from the default
image of the animation (the one that the format defines is to be used when animation is not
supported or is disabled), or, if there is no such image, the first frame of the
image, the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> must only be taken from the
default image of the animation (the one that the format defines is to be used when animation
is not supported or is disabled), or, if there is no such image, the first frame of the
animation.</p></li>

<li><p>If the <span>origin</span> of the <code>img</code> element's image is not the
Expand Down Expand Up @@ -90919,7 +90958,8 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be a copy of the frame at the
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be a copy of the frame at the
<span>current playback position</span>, at the <span>media resource</span>'s <span
data-x="concept-video-intrinsic-width">intrinsic width</span> and <span
data-x="concept-video-intrinsic-height">intrinsic height</span> (i.e. after any aspect-ratio
Expand Down Expand Up @@ -90954,8 +90994,10 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be a copy of the
<code>canvas</code> element's bitmap data, <span>cropped to the source
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be a copy of the
<code>canvas</code> element's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span>, <span>cropped to the source
rectangle</span>.</p></li>

<li><p>Set the <span data-x="concept-canvas-origin-clean">origin-clean</span> flag of the
Expand Down Expand Up @@ -91004,11 +91046,13 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be the image data read from the
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be the image data read from the
<code>Blob</code> object, <span>cropped to the source rectangle</span>. If this is an animated
image, the <code>ImageBitmap</code> object's bitmap data must only be taken from the default
image of the animation (the one that the format defines is to be used when animation is not
supported or is disabled), or, if there is no such image, the first frame of the
image, the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> must only be taken from the
default image of the animation (the one that the format defines is to be used when animation
is not supported or is disabled), or, if there is no such image, the first frame of the
animation.</p></li>

<li><p>Resolve the promise with the new <code>ImageBitmap</code> object as the value.</p></li>
Expand All @@ -91033,7 +91077,8 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be the image data given by the
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be the image data given by the
<code>ImageData</code> object, <span>cropped to the source rectangle</span>.</p></li>

<li><p>Return a new promise, but continue running these steps
Expand All @@ -91060,7 +91105,8 @@ interface <dfn>ImageBitmapFactories</dfn> {

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be a copy of the
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be a copy of the
<code>CanvasRenderingContext2D</code> object's <span>scratch bitmap</span>, <span>cropped to
the source rectangle</span>.</p></li>

Expand All @@ -91086,12 +91132,19 @@ interface <dfn>ImageBitmapFactories</dfn> {
<ol>

<li><p>If either the <var>sw</var> or <var>sh</var> arguments are specified
but zero, return a promise rejected with an <code>IndexSizeError</code> exception and abort these steps.</p></li>
but zero, return a promise rejected with an <code>IndexSizeError</code> exception and abort
these steps.</p></li>

<li><p>If image is <span data-x="concept-Transferable-neutered">neutered</span>, return a
promise rejected with an <code>InvalidStateError</code> exception and abort these
steps.</p></li>

<li><p>Create a new <code>ImageBitmap</code> object.</p></li>

<li><p>Let the <code>ImageBitmap</code> object's bitmap data be a copy of the <var>image</var>
argument's bitmap data, <span>cropped to the source rectangle</span>.</p></li>
<li><p>Let the <code>ImageBitmap</code> object's <span
data-x="concept-ImageBitmap-bitmap-data">bitmap data</span> be a copy of the <var>image</var>
argument's <span data-x="concept-ImageBitmap-bitmap-data">bitmap data</span>, <span>cropped
to the source rectangle</span>.</p></li>

<li><p>Set the <span data-x="concept-canvas-origin-clean">origin-clean</span> flag of the
<code>ImageBitmap</code> object's bitmap to the same value as the <span
Expand All @@ -91116,7 +91169,8 @@ interface <dfn>ImageBitmapFactories</dfn> {

<ol>

<li><p>Let <var>input</var> be the image data being cropped.</p></li>
<li><p>Let <var>input</var> be the <span data-x="concept-ImageBitmap-bitmap-data">bitmap
data</span> being cropped.</p></li>

<li><p>If the <var>sx</var>, <var>sy</var>, <var>sw</var>, and <var>sh</var> arguments are omitted, return <var>input</var>.</p></li>

Expand Down

0 comments on commit 334f9ed

Please sign in to comment.