<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.whatwg.org/index.php?action=history&amp;feed=atom&amp;title=Changes_to_ImageBitmap_for_OffscreenCanvas</id>
	<title>Changes to ImageBitmap for OffscreenCanvas - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.whatwg.org/index.php?action=history&amp;feed=atom&amp;title=Changes_to_ImageBitmap_for_OffscreenCanvas"/>
	<link rel="alternate" type="text/html" href="https://wiki.whatwg.org/index.php?title=Changes_to_ImageBitmap_for_OffscreenCanvas&amp;action=history"/>
	<updated>2026-04-05T16:45:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.whatwg.org/index.php?title=Changes_to_ImageBitmap_for_OffscreenCanvas&amp;diff=9945&amp;oldid=prev</id>
		<title>Junov at 15:09, 21 April 2015</title>
		<link rel="alternate" type="text/html" href="https://wiki.whatwg.org/index.php?title=Changes_to_ImageBitmap_for_OffscreenCanvas&amp;diff=9945&amp;oldid=prev"/>
		<updated>2015-04-21T15:09:55Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:09, 21 April 2015&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l4&quot;&gt;Line 4:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 4:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A common complaint from web developers writing applications that manipulate large images is that the browser tends to consume large amounts of RAM and GPU memory. Part of this is due to intermediate copies of image data that are made by the browser and transient copies that are kept around, awaiting garbage collection. Another complaint is that manipulation large images on the browser&amp;#039;s main thread often makes applications janky.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A common complaint from web developers writing applications that manipulate large images is that the browser tends to consume large amounts of RAM and GPU memory. Part of this is due to intermediate copies of image data that are made by the browser and transient copies that are kept around, awaiting garbage collection. Another complaint is that manipulation large images on the browser&amp;#039;s main thread often makes applications janky.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Specific use cases:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Specific use cases:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Generating pixel data in javascript, and bringing it to screen.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Generating &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;or processing &lt;/ins&gt;pixel data in javascript&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;, possibly in a Worker thread&lt;/ins&gt;, and bringing it to screen.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Taking a snapshot of canvas-rendered content and uploading it as an image file to a remote server, possibly using XHR2 with a progress updates.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Taking a snapshot of canvas-rendered content and uploading it as an image file to a remote server, possibly using XHR2 with a progress updates.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Using 2D canvas to produce images that are subsequently used as textures in WebGL.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Using 2D canvas to produce images that are subsequently used as textures in WebGL.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Transfer &lt;/del&gt;a canvas-rendered image to anywhere an image URL can be used (e.g. CSS properties)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Transferring &lt;/ins&gt;a canvas-rendered image to anywhere an image URL can be used (e.g. CSS properties)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Save locally rendered canvas content to a local disk.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Save locally rendered canvas content to a local disk.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Stream snapshots of a local canvas to a remote server. ex: Broadcasting a live presentation rendered in WebGL&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Stream snapshots of a local canvas to a remote server. ex: Broadcasting a live presentation rendered in WebGL&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l14&quot;&gt;Line 14:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 14:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Capturing a snapshot from a video stream (possibly WebRTC), and uploading the snapshot to a remote server.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Capturing a snapshot from a video stream (possibly WebRTC), and uploading the snapshot to a remote server.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Note: Many of these use cases were reported by web developpers in support of &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;implementing &lt;/ins&gt;the HTMLCanvasElement.toBlob interface&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;. Below we counter-propose that putting toBlob on ImageBitmap will serve those use cases better or as well as having toBlob on &amp;lt;canvas&amp;gt;&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Note: Many of these use cases were reported by web developpers in support of the HTMLCanvasElement.toBlob interface.&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Current Limitations ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Current Limitations ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The current API often forces the web developer to go through a canvas for moving pixel data. Because canvases are mutable, &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;avoiding &lt;/del&gt;intermediate copies &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;is &lt;/del&gt;often unavoidable, and may result in unnecessary multiply and divide by alpha, which is expensive and lossy.  ImageBitmap, being an opaque immutable object type would allow for low friction means of moving pixel data, but it is missing some functionality that prevents it from being a universal pixel vehicle. In particular, it is missing transfer methods (required for zero-copy behavior).  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The current API often forces the web developer to go through a canvas for moving pixel data. Because canvases are mutable, intermediate copies &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;are &lt;/ins&gt;often unavoidable, and may result in unnecessary multiply and divide by alpha, which is expensive and lossy.  ImageBitmap, being an opaque immutable object type would allow for low friction means of moving pixel data, but it is missing some functionality that prevents it from being a universal pixel vehicle. In particular, it is missing transfer methods (required for zero-copy behavior).  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Current Usage and Workarounds ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Current Usage and Workarounds ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l58&quot;&gt;Line 58:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 57:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Because ImageBitmap is immutable, no safety copy is required for toBlob to operate asynchronously. A counter argument to this is that an implementation of HTMLCanvasElement.toBlob could perform the copy lazily, only when the canvas backing is about to be mutated while a toBlob is in progress, thus performing a copy only in use case that require it. Though this is true, it results in performance characteritcs that may seem idiosyncratic to developers (i.e. the preformance of toBlob degrades if something is done to the canvas after calling toBlob.), as opposed to a flow that guarantees zero copies: OffscreenCanvas.transferToImageBitmap, followed by ImageBitmap.toBlob.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* Because ImageBitmap is immutable, no safety copy is required for toBlob to operate asynchronously. A counter argument to this is that an implementation of HTMLCanvasElement.toBlob could perform the copy lazily, only when the canvas backing is about to be mutated while a toBlob is in progress, thus performing a copy only in use case that require it. Though this is true, it results in performance characteritcs that may seem idiosyncratic to developers (i.e. the preformance of toBlob degrades if something is done to the canvas after calling toBlob.), as opposed to a flow that guarantees zero copies: OffscreenCanvas.transferToImageBitmap, followed by ImageBitmap.toBlob.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The close() method effectively neuters the ImageBitmap. It is a means of explicitly de-&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;allocate &lt;/del&gt;large resources, which avoids waiting for garbage collection, and therefore &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;reducing &lt;/del&gt;the frequency of GCs and &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;bringing &lt;/del&gt;down peak RAM consumption.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The close() method effectively neuters the ImageBitmap. It is a means of explicitly de-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;allocating &lt;/ins&gt;large resources, which avoids waiting for garbage collection, and therefore &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;reduces &lt;/ins&gt;the frequency of GCs and &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;brings &lt;/ins&gt;down peak RAM consumption.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==== Processing Model ====&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==== Processing Model ====&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Junov</name></author>
	</entry>
	<entry>
		<id>https://wiki.whatwg.org/index.php?title=Changes_to_ImageBitmap_for_OffscreenCanvas&amp;diff=9944&amp;oldid=prev</id>
		<title>Junov: Created page with &quot;:&#039;&#039;&#039;WORK IN PROGRESS&#039;&#039;&#039; &#039;&#039;Amendments to ImageBitmap to provide zero-copy paths for moving pixel data and for working with the OffscreenCanvas proposal&#039;&#039;  == Use Case Descripti...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.whatwg.org/index.php?title=Changes_to_ImageBitmap_for_OffscreenCanvas&amp;diff=9944&amp;oldid=prev"/>
		<updated>2015-04-17T15:40:16Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;:&amp;#039;&amp;#039;&amp;#039;WORK IN PROGRESS&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;Amendments to ImageBitmap to provide zero-copy paths for moving pixel data and for working with the OffscreenCanvas proposal&amp;#039;&amp;#039;  == Use Case Descripti...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;:&amp;#039;&amp;#039;&amp;#039;WORK IN PROGRESS&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;Amendments to ImageBitmap to provide zero-copy paths for moving pixel data and for working with the OffscreenCanvas proposal&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Use Case Description ==&lt;br /&gt;
A common complaint from web developers writing applications that manipulate large images is that the browser tends to consume large amounts of RAM and GPU memory. Part of this is due to intermediate copies of image data that are made by the browser and transient copies that are kept around, awaiting garbage collection. Another complaint is that manipulation large images on the browser&amp;#039;s main thread often makes applications janky.&lt;br /&gt;
Specific use cases:&lt;br /&gt;
* Generating pixel data in javascript, and bringing it to screen.&lt;br /&gt;
* Taking a snapshot of canvas-rendered content and uploading it as an image file to a remote server, possibly using XHR2 with a progress updates.&lt;br /&gt;
* Using 2D canvas to produce images that are subsequently used as textures in WebGL.&lt;br /&gt;
* Transfer a canvas-rendered image to anywhere an image URL can be used (e.g. CSS properties)&lt;br /&gt;
* Save locally rendered canvas content to a local disk.&lt;br /&gt;
* Stream snapshots of a local canvas to a remote server. ex: Broadcasting a live presentation rendered in WebGL&lt;br /&gt;
* Appending a locally rendered canvas image to form data as an image file.&lt;br /&gt;
* Save a canvas image locally with the anchor &amp;quot;download&amp;quot; attribute.&lt;br /&gt;
* Capturing a snapshot from a video stream (possibly WebRTC), and uploading the snapshot to a remote server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: Many of these use cases were reported by web developpers in support of the HTMLCanvasElement.toBlob interface.&lt;br /&gt;
&lt;br /&gt;
=== Current Limitations ===&lt;br /&gt;
The current API often forces the web developer to go through a canvas for moving pixel data. Because canvases are mutable, avoiding intermediate copies is often unavoidable, and may result in unnecessary multiply and divide by alpha, which is expensive and lossy.  ImageBitmap, being an opaque immutable object type would allow for low friction means of moving pixel data, but it is missing some functionality that prevents it from being a universal pixel vehicle. In particular, it is missing transfer methods (required for zero-copy behavior). &lt;br /&gt;
&lt;br /&gt;
=== Current Usage and Workarounds ===&lt;br /&gt;
&amp;#039;&amp;#039;Some evidence that this feature is desperately needed on the web.  You may provide a separate examples page for listing these.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
For sending image data to a remote server, a compressed image file in binary form is the preferred vehicle. This can currently be achieved by using HTMLCanvasElement.toBlob (or equivalent interface) with web browser that provide that API, or with this approach on other browsers: http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata.  This method has some disadvantages: because it lives on a DOM interface, it can only be invoked from the main thread; because the canvas backing editable, the implementation is required to make a read-only snapshot for itself; In many use cases, the canvas itself represent an additional copy of the image data.  Preventing the proliferation of copies of image data in RAM is very important for applications that manipulate large images (e.g. full res photos, maps), which are vulnerable to malfunctions cause by out-of-memory errors, particularly on mobile.&lt;br /&gt;
&lt;br /&gt;
Experience has shown that garbage collection is often a performance liability when dealing with large temporary objects, particularly those that consume GPU memory. The ability to explicity discard image buffers when they are no longer needed has proven to be widely useful with 2D canvas, which offer this possibility indirectly by setting the intrinsic size to 0.  This practice allows resources (RAM, GPU memory) to be freed as early as possible, hence avoiding process bloat, and it helps reduce the frequency of garbage collections, which can cause jank. Using ImageBitmaps as currently spec&amp;#039;ed implies losing this advantage.&lt;br /&gt;
&lt;br /&gt;
=== Benefits ===&lt;br /&gt;
&lt;br /&gt;
The proposed additions to the ImageBitmap interface aim to provide leaner browser memory consumption and fast, smoother performance for the above mentioned use cases.&lt;br /&gt;
&lt;br /&gt;
=== Requests for this Feature ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;cite&amp;gt;[http://example.com Source]&amp;lt;/cite&amp;gt; &amp;lt;blockquote&amp;gt;&amp;lt;p&amp;gt;I would like this feature ...&amp;lt;/p&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Proposed Solution ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Exposed=(Window,Worker)]&lt;br /&gt;
interface ImageBitmap implements Transferable {&lt;br /&gt;
  readonly attribute unsigned long width;&lt;br /&gt;
  readonly attribute unsigned long width;&lt;br /&gt;
  void close();&lt;br /&gt;
  // Throws a SecurityError if the OffscreenCanvas&amp;#039;s origin-clean flag&lt;br /&gt;
  // is set to false.&lt;br /&gt;
  Promise&amp;lt;Blob&amp;gt; toBlob(optional DOMString type, any... arguments);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Making ImageBitmap Transferrable allows it to be used as a zero-copy vehicle for passing pixel data between threads, hence reducing peak RAM consumption and avoiding the CPU cost of performing a copy.&lt;br /&gt;
&lt;br /&gt;
Offering toBlob on ImageBitmap, as opposed to HTMLCanvasElement:&lt;br /&gt;
* Allows to toBlob be invoked from a worker, which help reduce jank on the main thread (even if the encode is on a separate thread, make a copy and interacting with the blob store can jank the main thread).&lt;br /&gt;
* Allows the data flow to bypass the canvas (for cases where the source of the image data is not a canvas), therefore avoiding an alpha multiply+divide in some cases, and avoiding an unnecessary intermediate (the canvas itself)&lt;br /&gt;
* Because ImageBitmap is immutable, no safety copy is required for toBlob to operate asynchronously. A counter argument to this is that an implementation of HTMLCanvasElement.toBlob could perform the copy lazily, only when the canvas backing is about to be mutated while a toBlob is in progress, thus performing a copy only in use case that require it. Though this is true, it results in performance characteritcs that may seem idiosyncratic to developers (i.e. the preformance of toBlob degrades if something is done to the canvas after calling toBlob.), as opposed to a flow that guarantees zero copies: OffscreenCanvas.transferToImageBitmap, followed by ImageBitmap.toBlob.&lt;br /&gt;
&lt;br /&gt;
The close() method effectively neuters the ImageBitmap. It is a means of explicitly de-allocate large resources, which avoids waiting for garbage collection, and therefore reducing the frequency of GCs and bringing down peak RAM consumption.&lt;br /&gt;
&lt;br /&gt;
==== Processing Model ====&lt;br /&gt;
:&amp;#039;&amp;#039;Explanation of the changes introduced by this solution. It explains how the document is processed, and how errors are handled. This should be very clear, including things such as event timing if the solution involves events, how to create graphs representing the data in the case of semantic proposals, etc.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==== Limitations ==== &lt;br /&gt;
:&amp;#039;&amp;#039;Cases not covered by this solution in relation to the problem description; other problems with this solution, if any.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==== Implementation ==== &lt;br /&gt;
:&amp;#039;&amp;#039;Description of how and why browser vendors would take advantage of this feature.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==== Adoption ==== &lt;br /&gt;
:&amp;#039;&amp;#039;Reasons why page authors would use this solution.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Proposals]]&lt;/div&gt;</summary>
		<author><name>Junov</name></author>
	</entry>
</feed>